Оператор SyncLockSyncLock Statement

Применяет монопольную блокировку для блока инструкций, перед выполнением блока.Acquires an exclusive lock for a statement block before executing the block.

СинтаксисSyntax

SyncLock lockobject  
    [ block ]  
End SyncLock  

ЧастиParts

lockobject
Обязательный.Required. Выражение, возвращающее ссылку на объект.Expression that evaluates to an object reference.

block
Необязательный параметр.Optional. Блок операторов, которые должны выполняться, когда блокировка получена.Block of statements that are to execute when the lock is acquired.

End SyncLock
Завершает SyncLock блока.Terminates a SyncLock block.

ПримечанияRemarks

SyncLock Оператор гарантирует, что несколько потоков не выполняют блок операторов одновременно.The SyncLock statement ensures that multiple threads do not execute the statement block at the same time. SyncLock запрещает каждому потоку входе в блок, пока не выполняется ни один поток.SyncLock prevents each thread from entering the block until no other thread is executing it.

Наиболее распространенное использование SyncLock предназначены для защиты данных не будет обновляться одновременно более чем одним потоком.The most common use of SyncLock is to protect data from being updated by more than one thread simultaneously. Если операторы для работы с данными необходимо перейти к завершению работы без прерывания, поместите их внутри SyncLock блока.If the statements that manipulate the data must go to completion without interruption, put them inside a SyncLock block.

Блок операторов, защищенный монопольной блокировкой иногда называют критический раздел.A statement block protected by an exclusive lock is sometimes called a critical section.

ПравилаRules

  • Ветвление.Branching. Нельзя осуществлять ветвление в SyncLock заблокировать вне блока.You cannot branch into a SyncLock block from outside the block.

  • Значение объекта блокировки.Lock Object Value. Значение lockobject не может быть Nothing.The value of lockobject cannot be Nothing. Необходимо создать объект блокировки, прежде чем использовать его в SyncLock инструкции.You must create the lock object before you use it in a SyncLock statement.

    Не удается изменить значение lockobject при выполнении SyncLock блока.You cannot change the value of lockobject while executing a SyncLock block. Механизм требует, что объект блокировки остаются неизменными.The mechanism requires that the lock object remain unchanged.

  • Нельзя использовать Await оператор в SyncLock блока.You can't use the Await operator in a SyncLock block.

ПоведениеBehavior

  • Механизм.Mechanism. Когда поток достигает SyncLock инструкции, она оценивает lockobject выражение и приостанавливает выполнение, пока не получит монопольную блокировку для объекта, возвращаемого выражением.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. Когда другой поток достигает SyncLock инструкции, она не использовать блокировку пока первый поток выполняет End SyncLock инструкции.When another thread reaches the SyncLock statement, it does not acquire a lock until the first thread executes the End SyncLock statement.

  • Защищенные данные.Protected Data. Если lockobjectShared переменных, монопольная блокировка предотвращает поток в любом экземпляре класса выполнение SyncLock блокировать во время его выполнения любого другого потока.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. Это обеспечивает защиту данных, которая является общей для всех экземпляров.This protects data that is shared among all the instances.

    Если lockobject является переменной экземпляра (не Shared), Блокировка предотвращает одновременное выполнение потока в текущем экземпляре выполнения SyncLock блока, в то же время как другой поток, в том же экземпляре.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. Это обеспечивает защиту данных, содержащихся в отдельном экземпляре.This protects data maintained by the individual instance.

  • Получение и выпуск.Acquisition and Release. Объект SyncLock блок ведет себя как Try...Finally построения, в котором Try блок применяет монопольную блокировку на lockobject и Finally блок освобождает его.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. По этой причине SyncLock блок гарантирует освобождение блокировки, независимо от того, как выйти из блока.Because of this, the SyncLock block guarantees release of the lock, no matter how you exit the block. Это справедливо даже в случае необработанного исключения.This is true even in the case of an unhandled exception.

  • Платформа вызывает функцию.Framework Calls. SyncLock Блок получает и освобождает монопольную блокировку, вызывая Enter и Exit методы Monitor в класс System.Threading пространства имен.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.

Примеры программированияProgramming Practices

lockobject Выражение всегда следует проверять на объект, к которому относится исключительно к классу.The lockobject expression should always evaluate to an object that belongs exclusively to your class. Следует объявлять Private объектной переменной, чтобы защитить данные, относящиеся к текущим экземпляром, или Private Shared объектной переменной, чтобы защитить данные, общие для всех экземпляров.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.

Не следует использовать Me ключевое слово для предоставления блокировки для экземпляра объекта данных.You should not use the Me keyword to provide a lock object for instance data. Если код, внешним по отношению к классу имеет ссылку на экземпляр вашего класса, он может использовать эту ссылку, как объект блокировки для SyncLock блок полностью отличаться от впечатления разработчика, защиты данных.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. Таким образом, класс и другой класс может заблокировать друг с другом выполнение их несвязанных SyncLock блоков.In this way, your class and the other class could block each other from executing their unrelated SyncLock blocks. Аналогичным образом, блокировка строки может вызывать затруднения, так как любой другой код в процесс, использующий ту же строку будет совместно использовать ту же блокировку.Similarly locking on a string can be problematic since any other code in the process using the same string will share the same lock.

Также не следует использовать Me.GetType метод, чтобы предоставить объект блокировки для общих данных.You should also not use the Me.GetType method to provide a lock object for shared data. Это обусловлено GetType всегда возвращает тот же Type объект для заданного имени класса.This is because GetType always returns the same Type object for a given class name. Внешний код может осуществлять вызов GetType в классе и получить тот же объект блокировки, которые вы используете.External code could call GetType on your class and obtain the same lock object you are using. Это может привести в обоих классах блокировки друг с другом и с их SyncLock блоков.This would result in the two classes blocking each other from their SyncLock blocks.

ПримерыExamples

ОписаниеDescription

В следующем примере класс, который поддерживает простой список сообщений.The following example shows a class that maintains a simple list of messages. Сообщения хранятся в массиве, а последний элемент этого массива в переменной.It holds the messages in an array and the last used element of that array in a variable. addAnotherMessage Процедура увеличивает значение последнего элемента и сохраняет новое сообщение.The addAnotherMessage procedure increments the last element and stores the new message. Эти две операции защищены с помощью SyncLock и End SyncLock инструкции, так как после последнего элемента был увеличен, должен храниться новое сообщение, прежде, чем любой другой поток может снова увеличить последнего элемента.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.

Если simpleMessageList один список сообщений для всех его экземпляров, переменные общих классов messagesList и messagesLast должна быть объявлена как Shared.If the simpleMessageList class shared one list of messages among all its instances, the variables messagesList and messagesLast would be declared as Shared. В данном случае переменная messagesLock также должен быть Shared, таким образом, чтобы могла быть объект блокировки, используемые каждым экземпляром.In this case, the variable messagesLock should also be Shared, so that there would be a single lock object used by every instance.

КодCode

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

ОписаниеDescription

В следующем примере используются потоки и SyncLock.The following example uses threads and SyncLock. Поскольку SyncLock присутствует оператор, блокировка оператора является критической секции и balance никогда не будет отрицательным числом.As long as the SyncLock statement is present, the statement block is a critical section and balance never becomes a negative number. Вы можете закомментировать SyncLock и End SyncLock инструкции, чтобы увидеть эффект пропускают SyncLock ключевое слово.You can comment out the SyncLock and End SyncLock statements to see the effect of leaving out the SyncLock keyword.

КодCode

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

КомментарииComments

См. такжеSee also