Istruzione SyncLockSyncLock Statement

Acquisisce un blocco esclusivo per un blocco di istruzioni prima di eseguire il blocco.Acquires an exclusive lock for a statement block before executing the block.

SintassiSyntax

SyncLock lockobject  
    [ block ]  
End SyncLock  

PartiParts

lockobject
Obbligatorio.Required. Espressione che restituisce un riferimento all'oggetto.Expression that evaluates to an object reference.

block
Facoltativo.Optional. Blocco di istruzioni da eseguire quando viene acquisito il blocco.Block of statements that are to execute when the lock is acquired.

End SyncLock
Termina un SyncLock blocco.Terminates a SyncLock block.

NoteRemarks

Il SyncLock istruzione garantisce che più thread non eseguano il blocco di istruzioni nello stesso momento.The SyncLock statement ensures that multiple threads do not execute the statement block at the same time. SyncLock impedisce ogni thread di immettere il blocco fino a quando non viene eseguito alcun altro thread.SyncLock prevents each thread from entering the block until no other thread is executing it.

L'uso più comune di SyncLock consiste nel proteggere i dati vengano aggiornati da più thread contemporaneamente.The most common use of SyncLock is to protect data from being updated by more than one thread simultaneously. Se le istruzioni che modificano i dati devono andare fino al completamento senza interruzioni, inserirli all'interno di un SyncLock blocco.If the statements that manipulate the data must go to completion without interruption, put them inside a SyncLock block.

Un blocco di istruzioni protetto da un blocco esclusivo viene a volte chiamato un sezione critica.A statement block protected by an exclusive lock is sometimes called a critical section.

RegoleRules

  • Creazione di rami.Branching. È possibile creare rami in un SyncLock impedisce all'esterno del blocco.You cannot branch into a SyncLock block from outside the block.

  • Valore dell'oggetto di blocco.Lock Object Value. Il valore di lockobject non può essere Nothing.The value of lockobject cannot be Nothing. È necessario creare l'oggetto di blocco prima di usarla in un SyncLock istruzione.You must create the lock object before you use it in a SyncLock statement.

    Non è possibile modificare il valore di lockobject durante l'esecuzione di un SyncLock blocco.You cannot change the value of lockobject while executing a SyncLock block. Il meccanismo di richiede che l'oggetto blocco rimangono invariati.The mechanism requires that the lock object remain unchanged.

  • Non è possibile usare la Await operatore in un SyncLock blocco.You can't use the Await operator in a SyncLock block.

ComportamentoBehavior

  • Meccanismo.Mechanism. Quando un thread raggiunge la SyncLock istruzione, viene restituito il lockobject espressione e sospende l'esecuzione fino a quando non acquisisce un blocco esclusivo sull'oggetto restituito dall'espressione.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. Quando un altro thread raggiunge la SyncLock istruzione, non acquisisce un blocco fino a quando non viene eseguito il primo thread la End SyncLock istruzione.When another thread reaches the SyncLock statement, it does not acquire a lock until the first thread executes the End SyncLock statement.

  • Dati protetti.Protected Data. Se lockobject è un Shared variabile, il blocco esclusivo impedisce a un thread in qualsiasi istanza della classe dall'esecuzione di SyncLock bloccarsi mentre viene eseguito un altro thread.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. Consente di proteggere i dati condivisi fra tutte le istanze.This protects data that is shared among all the instances.

    Se lockobject è una variabile di istanza (non Shared), il blocco impedisce a un thread in esecuzione nell'istanza corrente di eseguire il SyncLock blocco allo stesso tempo come un altro thread nella stessa istanza.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. Ciò consente di proteggere dati gestiti da istanza singola.This protects data maintained by the individual instance.

  • Acquisizione e il rilascio.Acquisition and Release. Oggetto SyncLock blocco si comporta come un Try...Finally costruzione in cui le Try blocco acquisisce un blocco esclusivo sul lockobject e il Finally lo rilascia blocco.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. Per questo motivo, il SyncLock garantisce il rilascio del blocco, indipendentemente dal modo in cui si esce dal blocco.Because of this, the SyncLock block guarantees release of the lock, no matter how you exit the block. Questo vale anche in caso di un'eccezione non gestita.This is true even in the case of an unhandled exception.

  • Chiamate di Framework.Framework Calls. Il SyncLock blocco acquisisce e rilascia il blocco esclusivo chiamando il Enter e Exit metodi del Monitor classe la System.Threading dello spazio dei nomi.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.

Procedure consigliate di programmazioneProgramming Practices

Il lockobject espressione deve sempre restituire un oggetto a cui appartiene esclusivamente alla classe.The lockobject expression should always evaluate to an object that belongs exclusively to your class. È necessario dichiarare un Private variabile di oggetto per proteggere i dati appartenenti all'istanza corrente, o un Private Shared variabile oggetto per proteggere i dati comuni a tutte le istanze.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.

È consigliabile non usare il Me (parola chiave) per fornire un blocco di dati dell'oggetto, ad esempio.You should not use the Me keyword to provide a lock object for instance data. Se il codice esterno alla classe ha un riferimento a un'istanza della classe, è Impossibile utilizzare il riferimento come un oggetto di blocco per un SyncLock blocco completamente diversa da quelle in uso, protezione dei dati diversi.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. In questo modo, la classe e l'altra classe può bloccare loro l'esecuzione di loro non correlati SyncLock blocchi.In this way, your class and the other class could block each other from executing their unrelated SyncLock blocks. Analogamente, il blocco su una stringa può essere problematico perché qualsiasi altro codice nel processo che usa la stessa stringa condividerà lo stesso blocco.Similarly locking on a string can be problematic since any other code in the process using the same string will share the same lock.

È inoltre consigliabile non utilizzare il Me.GetType metodo per fornire un oggetto di blocco per i dati condivisi.You should also not use the Me.GetType method to provide a lock object for shared data. Infatti GetType restituisce sempre lo stesso Type oggetto per un determinato nome di classe.This is because GetType always returns the same Type object for a given class name. Impossibile chiamare codice esterno GetType nella classe e ottenere lo stesso oggetto di blocco in uso.External code could call GetType on your class and obtain the same lock object you are using. In questo modo, le due classi di blocco tra loro da loro SyncLock blocchi.This would result in the two classes blocking each other from their SyncLock blocks.

EsempiExamples

DescrizioneDescription

Nell'esempio seguente viene illustrata una classe che gestisce un elenco semplice di messaggi.The following example shows a class that maintains a simple list of messages. Contiene i messaggi in una matrice e l'ultimo elemento della matrice di utilizzato in una variabile.It holds the messages in an array and the last used element of that array in a variable. Il addAnotherMessage procedure incrementa l'ultimo elemento e archivia il nuovo messaggio.The addAnotherMessage procedure increments the last element and stores the new message. Queste due operazioni sono protetti dal SyncLock e End SyncLock (istruzioni), poiché dopo l'ultimo elemento è stato incrementato, il nuovo messaggio deve essere archiviato prima di qualsiasi altro thread può incrementare nuovamente l'ultimo elemento.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.

Se il simpleMessageList classe condivisa un elenco di messaggi tra tutte le istanze, le variabili messagesList e messagesLast sarebbe dichiarata come Shared.If the simpleMessageList class shared one list of messages among all its instances, the variables messagesList and messagesLast would be declared as Shared. In questo caso, la variabile messagesLock deve essere anche Shared, in modo che non vi sarà un unico oggetto blocco usato da ogni istanza.In this case, the variable messagesLock should also be Shared, so that there would be a single lock object used by every instance.

CodiceCode

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

DescrizioneDescription

L'esempio seguente usa i thread e SyncLock.The following example uses threads and SyncLock. Fino a quando la SyncLock istruzione è presente, il blocco di istruzioni è una sezione critica e balance non diventerà mai un numero negativo.As long as the SyncLock statement is present, the statement block is a critical section and balance never becomes a negative number. È possibile impostare come commento il SyncLock e End SyncLock istruzioni per visualizzare l'effetto dell'omissione di SyncLock (parola chiave).You can comment out the SyncLock and End SyncLock statements to see the effect of leaving out the SyncLock keyword.

CodiceCode

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

CommentiComments

Vedere ancheSee also