SyncLock-AnweisungSyncLock Statement

Erhält eine exklusive Sperre für einen Anweisungsblock, bevor der-Block ausgeführt wird.Acquires an exclusive lock for a statement block before executing the block.

SyntaxSyntax

SyncLock lockobject  
    [ block ]  
End SyncLock  

TeileParts

lockobject
Erforderlich.Required. Ausdruck, der zu einem Objekt Verweis ausgewertet wird.Expression that evaluates to an object reference.

block
Dies ist optional.Optional. Ein Block von-Anweisungen, die ausgeführt werden sollen, wenn die Sperre abgerufen wird.Block of statements that are to execute when the lock is acquired.

End SyncLock
Beendet einen SyncLock-Block.Terminates a SyncLock block.

HinweiseRemarks

Die SyncLock-Anweisung stellt sicher, dass der Anweisungsblock nicht gleichzeitig von mehreren Threads ausgeführt wird.The SyncLock statement ensures that multiple threads do not execute the statement block at the same time. SyncLock verhindert, dass jeder Thread den Block eingibt, bis er von keinem anderen Thread ausgeführt wird.SyncLock prevents each thread from entering the block until no other thread is executing it.

Die häufigste Verwendung von SyncLock besteht darin, Daten vor der gleichzeitigen Aktualisierung durch mehr als einen Thread zu schützen.The most common use of SyncLock is to protect data from being updated by more than one thread simultaneously. Wenn die Anweisungen, die die Daten bearbeiten, ohne Unterbrechung in den Abschluss gehen müssen, platzieren Sie Sie in einem SyncLock-Block.If the statements that manipulate the data must go to completion without interruption, put them inside a SyncLock block.

Ein Anweisungsblock, der durch eine exklusive Sperre geschützt ist, wird manchmal als kritischer Abschnittbezeichnet.A statement block protected by an exclusive lock is sometimes called a critical section.

RegelnRules

  • Verzweigung.Branching. Sie können nicht von außerhalb des Blocks in einen SyncLock Block verzweigen.You cannot branch into a SyncLock block from outside the block.

  • Objektwert sperren.Lock Object Value. Der Wert von lockobject kann nicht Nothing werden.The value of lockobject cannot be Nothing. Sie müssen das Lock-Objekt erstellen, bevor Sie es in einer SyncLock-Anweisung verwenden.You must create the lock object before you use it in a SyncLock statement.

    Der Wert von lockobject kann beim Ausführen eines SyncLock Blocks nicht geändert werden.You cannot change the value of lockobject while executing a SyncLock block. Der Mechanismus erfordert, dass das Sperr Objekt unverändert bleibt.The mechanism requires that the lock object remain unchanged.

  • Sie können den Erwartungs Operator nicht in einem SyncLock-Block verwenden.You can't use the Await operator in a SyncLock block.

VerhaltenBehavior

  • Verfahren.Mechanism. Wenn ein Thread die SyncLock-Anweisung erreicht, wertet er den lockobject Ausdruck aus und hält die Ausführung an, bis er eine exklusive Sperre für das Objekt erhält, das vom Ausdruck zurückgegeben wird.When a thread reaches the SyncLock statement, it evaluates the lockobject expression and suspends execution until it acquires an exclusive lock on the object returned by the expression. Wenn ein anderer Thread die SyncLock-Anweisung erreicht, erhält er erst dann eine Sperre, wenn der erste Thread die End SyncLock-Anweisung ausführt.When another thread reaches the SyncLock statement, it does not acquire a lock until the first thread executes the End SyncLock statement.

  • Geschützte Daten.Protected Data. Wenn lockobject eine Shared Variable ist, verhindert die exklusive Sperre, dass ein Thread in einer Instanz der Klasse den SyncLock Block ausführt, während er von einem anderen Thread ausgeführt wird.If lockobject is a Shared variable, the exclusive lock prevents a thread in any instance of the class from executing the SyncLock block while any other thread is executing it. Dies schützt Daten, die von allen Instanzen gemeinsam genutzt werden.This protects data that is shared among all the instances.

    Wenn lockobject eine Instanzvariable (nicht Shared) ist, verhindert die Sperre, dass ein Thread, der in der aktuellen Instanz ausgeführt wird, den SyncLock Block gleichzeitig mit einem anderen Thread in derselben Instanz ausführt.If lockobject is an instance variable (not Shared), the lock prevents a thread running in the current instance from executing the SyncLock block at the same time as another thread in the same instance. Dadurch werden die Daten geschützt, die von der einzelnen Instanz verwaltet werden.This protects data maintained by the individual instance.

  • Erwerb und Release.Acquisition and Release. Ein SyncLock-Block verhält sich wie eine Try...Finally Konstruktion, in der der Try Block eine exklusive Sperre für lockobject erhält und der Finally Block diese freigibt.A SyncLock block behaves like a Try...Finally construction in which the Try block acquires an exclusive lock on lockobject and the Finally block releases it. Aus diesem Grund garantiert der SyncLock Block die Freigabe der Sperre, unabhängig davon, wie Sie den Block beenden.Because of this, the SyncLock block guarantees release of the lock, no matter how you exit the block. Dies gilt auch im Fall einer nicht behandelten Ausnahme.This is true even in the case of an unhandled exception.

  • Framework-Aufrufe.Framework Calls. Der SyncLock-Block übernimmt die exklusive Sperre und gibt Sie frei, indem Sie die Methoden Enter und Exit der Monitor-Klasse im System.Threading-Namespace aufrufen.The SyncLock block acquires and releases the exclusive lock by calling the Enter and Exit methods of the Monitor class in the System.Threading namespace.

ProgrammierverfahrenProgramming Practices

Der lockobject Ausdruck sollte immer zu einem Objekt ausgewertet werden, das exklusiv zu ihrer Klasse gehört.The lockobject expression should always evaluate to an object that belongs exclusively to your class. Sie sollten eine Private Objekt Variable deklarieren, um Daten zu schützen, die zur aktuellen Instanz gehören, oder eine Private Shared Objekt Variable, um die Daten zu schützen, die für alle Instanzen gemeinsam sind.You should declare a Private object variable to protect data belonging to the current instance, or a Private Shared object variable to protect data common to all instances.

Sie sollten das Me-Schlüsselwort nicht verwenden, um ein Sperr Objekt für Instanzdaten bereitzustellen.You should not use the Me keyword to provide a lock object for instance data. Wenn der Code, der sich außerhalb ihrer Klasse befindet, einen Verweis auf eine Instanz der Klasse enthält, könnte dieser Verweis als Sperr Objekt für einen SyncLock Block verwendet werden, der sich vollständig von Ihnen unterscheidet und verschiedene Daten schützt.If code external to your class has a reference to an instance of your class, it could use that reference as a lock object for a SyncLock block completely different from yours, protecting different data. Auf diese Weise können Ihre Klasse und die andere Klasse verhindern, dass Sie Ihre nicht verknüpften SyncLock Blöcke ausführen.In this way, your class and the other class could block each other from executing their unrelated SyncLock blocks. Ähnliches Sperren für eine Zeichenfolge können problematisch sein, da jeder andere Code im Prozess, der dieselbe Zeichenfolge verwendet, dieselbe Sperre gemeinsam verwendet.Similarly locking on a string can be problematic since any other code in the process using the same string will share the same lock.

Sie sollten auch die Me.GetType-Methode nicht verwenden, um ein Sperr Objekt für freigegebene Daten bereitzustellen.You should also not use the Me.GetType method to provide a lock object for shared data. Der Grund hierfür ist, dass GetType immer dasselbe Type Objekt für einen angegebenen Klassennamen zurückgibt.This is because GetType always returns the same Type object for a given class name. Externer Code könnte GetType für Ihre Klasse abrufen und das gleiche Sperr Objekt erhalten, das Sie verwenden.External code could call GetType on your class and obtain the same lock object you are using. Dies würde dazu führen, dass die beiden Klassen Ihre SyncLock Blöcke gegenseitig blockieren.This would result in the two classes blocking each other from their SyncLock blocks.

BeispieleExamples

BeschreibungDescription

Das folgende Beispiel zeigt eine Klasse, die eine einfache Liste von Nachrichten verwaltet.The following example shows a class that maintains a simple list of messages. Sie enthält die Nachrichten in einem Array und das zuletzt verwendete Element dieses Arrays in einer Variablen.It holds the messages in an array and the last used element of that array in a variable. Die addAnotherMessage Prozedur erhöht das letzte Element und speichert die neue Nachricht.The addAnotherMessage procedure increments the last element and stores the new message. Diese beiden Vorgänge werden durch die Anweisungen SyncLock und End SyncLock geschützt, denn nachdem das letzte Element inkrementiert wurde, muss die neue Nachricht gespeichert werden, bevor ein anderer Thread das letzte Element erneut erhöhen kann.Those two operations are protected by the SyncLock and End SyncLock statements, because once the last element has been incremented, the new message must be stored before any other thread can increment the last element again.

Wenn die simpleMessageList-Klasse eine Liste der Nachrichten für alle Instanzen freigegeben hat, werden die Variablen messagesList und messagesLast als Shared deklariert.If the simpleMessageList class shared one list of messages among all its instances, the variables messagesList and messagesLast would be declared as Shared. In diesem Fall sollte die Variable messagesLock ebenfalls Shared werden, damit für jede Instanz ein einzelnes Sperr Objekt verwendet werden kann.In this case, the variable messagesLock should also be Shared, so that there would be a single lock object used by every instance.

CodeCode

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

BeschreibungDescription

Im folgenden Beispiel werden Threads und SyncLock verwendet.The following example uses threads and SyncLock. Solange die SyncLock-Anweisung vorhanden ist, ist der Anweisungsblock ein kritischer Abschnitt und balance nie eine negative Zahl.As long as the SyncLock statement is present, the statement block is a critical section and balance never becomes a negative number. Sie können die Anweisungen SyncLock und End SyncLock auskommentieren, um die Auswirkung der Ausgabe des SyncLock-Schlüssel Worts anzuzeigen.You can comment out the SyncLock and End SyncLock statements to see the effect of leaving out the SyncLock keyword.

CodeCode

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

KommentareComments

Siehe auchSee also