Udostępnij za pośrednictwem


SyncLock wyciągu

Uzyskuje blokadę wyłączności dla bloku instrukcji przed wykonaniem bloku.

SyncLock lockobject
    [ block ]
End SyncLock

Części

  • lockobject
    Wymagane.Wyrażenie, którego wynikiem jest odwołanie do obiektu.

  • block
    Opcjonalne.Blok instrukcji, które są po blokady.

  • End SyncLock
    Kończy SyncLock bloku.

Uwagi

SyncLock Instrukcji gwarantuje, że wiele wątków nie wykonanie instrukcji bloku w tym samym czasie.SyncLockKażdy wątek uniemożliwia wprowadzanie bloku aż żaden inny wątek jest on wykonywany.

Najczęściej z SyncLock jest ochrona danych przed aktualizowany przez więcej niż jeden wątek jednocześnie.Jeśli w instrukcji, które manipulowania danymi, należy przejść do zakończenia bez przerwy, umieść je wewnątrz SyncLock bloku.

Chronione przez blokadę wyłączności blok instrukcji jest czasami nazywany sekcji krytycznej.

Zasady

  • Rozgałęzianie.Nie Rozgałęzienie do SyncLock zablokować z poza blokiem.

  • Zablokuj wartości obiektu.Wartość lockobject nie może być Nothing.Należy utworzyć obiekt Zablokuj przed użyciem go w SyncLock instrukcji.

    Nie można zmienić wartości lockobject podczas wykonywania SyncLock bloku.Mechanizm wymaga, aby zablokować obiektu pozostają niezmienione.

  • Nie można użyć Await operatora w SyncLock bloku.

Zachowanie

  • Mechanizm.Gdy wątek osiągnie SyncLock wynikiem instrukcji, lockobject wyrażenie i zawiesza wykonywanie aż kupuje blokadę wyłączności na obiekt zwrócony przez wyrażenie.Gdy inny wątek osiągnie SyncLock instrukcji, to nie nabywa blokady aż pierwszy wątek wykonuje End SyncLock instrukcji.

  • Chronionych danych.Jeśli lockobject jest Shared zmiennej, blokada wyłączności uniemożliwia wątek w dowolnej instancji klasy wykonywanie SyncLock blokowanie, podczas gdy inny wątek jest on wykonywany.Chroni to dane wspólne wszystkich instancji.

    Jeśli lockobject jest zmienną instancji (nie Shared), Blokada zapobiega wątek działający w bieżącej instancji wykonywanie SyncLock bloku jednocześnie inny wątek w tym samym wystąpieniu.Chroni to dane obsługiwane przez poszczególnych instancji.

  • Nabycie i wydania.A SyncLock bloku zachowuje się jak Try...Finally konstrukcji, w którym Try bloku przejmuje wyłączną blokadę na lockobject i Finally zwolni blok.W związku z tym SyncLock bloku gwarancje release blokady, niezależnie od tego, jak zakończyć bloku.Jest to nawet w przypadku nieobsłużonego wyjątku.

  • Ramy wywołań.SyncLock Bloku nabywa i zwalnia blokadę wyłączności przez wywołanie Enter i Exit metody Monitor klasy w System.Threading obszaru nazw.

Programowanie praktyk

lockobject Wyrażenia powinna zawsze być obiekt, który należy wyłącznie do swojej klasy.Należy zadeklarować Private zmienną obiektu, aby chronić dane należące do bieżącego wystąpienia lub Private Shared zmienną obiektu, aby chronić dane wspólne dla wszystkich wystąpień.

Nie należy używać Me słowo kluczowe, aby zapewnić blokady, na przykład obiekt danych.Jeśli kod zewnętrzny względem klasy zawiera odwołanie do instancji klasy, można użyć tego odwołania jako obiekt blokady dla SyncLock bloku całkowicie różna od zamierzonej, ochrona różnych danych.W ten sposób klasy i inne klasy może blokować wzajemnie wykonywanie ich niepowiązanych SyncLock bloków.Podobnie blokowania na ciąg może być problematyczne, ponieważ inny kod procesu przy użyciu samego ciągu będzie udostępniać blokadę.

Ponadto nie należy korzystać z Me.GetType metodę w celu zapewnienia zablokować obiektu dla udostępnianych danych.Wynika to z GetType zawsze zwraca to samo Type nazwę danej klasy obiektu.Kod zewnętrzny może wywołać GetType w klasie i uzyskania są przy użyciu tego samego obiektu blokady.Spowodowałoby to dwie klasy blokowania innych z ich SyncLock bloków.

Przykłady

3a86s51t.collapse_all(pl-pl,VS.110).gifOpis

Poniższy przykład pokazuje klasy, która utrzymuje proste listy wiadomości.Przechowuje wiadomości w tablicy i ostatni używany element tablicy w zmiennej.addAnotherMessage Procedury zwiększa ostatni element i zapisuje nowe wiadomości.Te dwie operacje są chronione przez SyncLock i End SyncLock instrukcji, ponieważ po ostatnim elementem została zwiększona, nowe wiadomości muszą być przechowywane przed inny wątek może zwiększać ostatni element ponownie.

Jeśli simpleMessageList klasy udostępnione jednej listy wiadomości między wszystkie jego wystąpienia, zmienne messagesList i messagesLast mogłyby być zadeklarowany jako Shared.W przypadku zmiennej messagesLock może być również Shared, dzięki czemu będzie obiekt pojedynczej blokady używane przez każde wystąpienie.

3a86s51t.collapse_all(pl-pl,VS.110).gifKod

Class simpleMessageList
    Public messagesList() As String = New String(50) {}
    Public messagesLast As Integer = -1
    Private messagesLock As New Object
    Public Sub addAnotherMessage(ByVal newMessage As String)
        SyncLock messagesLock
            messagesLast += 1
            If messagesLast < messagesList.Length Then
                messagesList(messagesLast) = newMessage
            End If
        End SyncLock
    End Sub
End Class

3a86s51t.collapse_all(pl-pl,VS.110).gifOpis

Poniższy przykład używa wątków i SyncLock.Tak długo, jak SyncLock deklaracji, instrukcji bloku jest sekcji krytycznej i balance nigdy nie staje się liczbę ujemną.Można wykomentować SyncLock i End SyncLock instrukcji, aby zobaczyć efekt pomijając SyncLock słowa kluczowego.

3a86s51t.collapse_all(pl-pl,VS.110).gifKod

Imports System.Threading

Module Module1

    Class Account
        Dim thisLock As New Object
        Dim balance As Integer

        Dim r As New Random()

        Public Sub New(ByVal initial As Integer)
            balance = initial
        End Sub

        Public Function Withdraw(ByVal amount As Integer) As Integer
            ' This condition will never be true unless the SyncLock statement
            ' is commented out:
            If balance < 0 Then
                Throw New Exception("Negative Balance")
            End If

            ' Comment out the SyncLock and End SyncLock lines to see
            ' the effect of leaving out the SyncLock keyword.
            SyncLock thisLock
                If balance >= amount Then
                    Console.WriteLine("Balance before Withdrawal :  " & balance)
                    Console.WriteLine("Amount to Withdraw        : -" & amount)
                    balance = balance - amount
                    Console.WriteLine("Balance after Withdrawal  :  " & balance)
                    Return amount
                Else
                    ' Transaction rejected.
                    Return 0
                End If
            End SyncLock
        End Function

        Public Sub DoTransactions()
            For i As Integer = 0 To 99
                Withdraw(r.Next(1, 100))
            Next
        End Sub
    End Class

    Sub Main()
        Dim threads(10) As Thread
        Dim acc As New Account(1000)

        For i As Integer = 0 To 9
            Dim t As New Thread(New ThreadStart(AddressOf acc.DoTransactions))
            threads(i) = t
        Next

        For i As Integer = 0 To 9
            threads(i).Start()
        Next
    End Sub

End Module

Zobacz też

Informacje

System.Threading

Monitor

Wątek synchronizacji (C# i Visual Basic)

Inne zasoby

Wątki (C# i Visual Basic)