SyncLock Deyimi

Bloğu yürütmeden önce bir deyim bloğu için özel bir kilit alır.

Sözdizimi

SyncLock lockobject  
    [ block ]  
End SyncLock  

Parça

lockobject
Gerekli. Nesne başvurusu olarak değerlendirilen ifade.

block
isteğe bağlı. Kilit alınırken yürütülecek deyim bloğu.

End SyncLock
Bir SyncLock bloğu sonlandırır.

Açıklamalar

deyimi, SyncLock birden çok iş parçacığının deyim bloğunu aynı anda yürütmemesini sağlar. SyncLock , başka bir iş parçacığı yürütmeden her iş parçacığının bloğu girmesini engeller.

en yaygın kullanımı SyncLock , verilerin aynı anda birden fazla iş parçacığı tarafından güncelleştirilmesinin korunmasıdır. Verileri işleyen deyimlerin kesinti olmadan tamamlanması gerekiyorsa, bunları bir SyncLock bloğun içine yerleştirin.

Özel kullanım kilidi tarafından korunan bir deyim bloğu bazen kritik bölüm olarak adlandırılır.

Kurallar

  • Dallanma. Bloğun dışından bir SyncLock bloğa dallanamaz.

  • Nesne Değerini Kilitle. değeri lockobject olamaz Nothing. Bir deyimde SyncLock kullanmadan önce lock nesnesini oluşturmanız gerekir.

    Bir SyncLock bloğu yürütürken değerini lockobject değiştiremezsiniz. Mekanizma, kilit nesnesinin değişmeden kalmasını gerektirir.

  • Bir blokta SyncLock Await işlecini kullanamazsınız.

Davranış

  • Mekanizması. bir iş parçacığı deyimine SyncLock ulaştığında, ifadeyi lockobject değerlendirir ve ifade tarafından döndürülen nesne üzerinde özel bir kilit elde edene kadar yürütmeyi askıya alır. Başka bir iş parçacığı deyimine SyncLock ulaştığında, ilk iş parçacığı deyimini yürütene End SyncLock kadar kilit almaz.

  • Korumalı Veriler. Bir Shared değişkenselockobject, özel kullanım kilidi sınıfın herhangi bir örneğindeki bir iş parçacığının bloğu başka bir iş parçacığı yürütürken SyncLock yürütmesini engeller. Bu, tüm örnekler arasında paylaşılan verileri korur.

    Bir örnek değişkeniyse lockobject (değil Shared), kilit geçerli örnekte çalışan bir iş parçacığının bloğu aynı örnekteki başka bir iş parçacığıyla aynı anda yürütmesini SyncLock engeller. Bu, tek tek örnek tarafından tutulan verileri korur.

  • Edinme ve Serbest Bırakma. BlokSyncLock, bloğun özel bir Try...Finally kilit lockobject aldığı ve bloğun TryFinally onu serbest bıraktığı bir yapı gibi davranır. Bu nedenle blok, SyncLock blok nasıl çıksanız da kilidin serbest bırakılmasını garanti eder. İşlenmeyen bir özel durum söz konusu olduğunda bile bu durum geçerlidir.

  • Çerçeve Çağrıları. blokSyncLock, ad alanında sınıfının System.Threading ve yöntemlerini Monitor çağırarak Enter özel kilidi alır ve Exit serbest bırakır.

Programlama Uygulamaları

İfade her lockobject zaman yalnızca sınıfınıza ait bir nesne olarak değerlendirilmelidir. Geçerli örneğe ait verileri korumak için bir Private nesne değişkeni veya tüm örneklerde ortak olan verileri korumak için bir Private Shared nesne değişkeni bildirmeniz gerekir.

Örnek verileri için bir kilit nesnesi sağlamak için anahtar sözcüğünü Me kullanmamalısınız. Sınıfınızın dışındaki kodun sınıfınızın bir örneğine bir başvurusu varsa, bu başvuru sizinkilerden tamamen farklı bir SyncLock blok için kilit nesnesi olarak kullanabilir ve farklı verileri koruyabilir. Bu şekilde, sınıfınız ve diğer sınıf birbiriyle ilişkili SyncLock olmayan blokları yürütmelerini engelleyebilir. Aynı dizeyi kullanan işlemdeki diğer kodlar aynı kilidi paylaşacağı için bir dizede de benzer şekilde kilitleme sorunlu olabilir.

Paylaşılan veriler için bir kilit nesnesi sağlamak için yöntemini de kullanmamalısınız Me.GetType . Bunun nedeni GetType her zaman belirli bir sınıf adı için aynı Type nesneyi döndürmesidir. Dış kod sınıfınızda çağrı GetType yapabilir ve kullandığınız aynı kilit nesnesini alabilir. Bu, iki sınıfın birbirini bloklarından engellemesine SyncLock neden olur.

Örnekler

Açıklama

Aşağıdaki örnekte, iletilerin basit bir listesini tutan bir sınıf gösterilmektedir. Bir dizideki iletileri ve bu dizinin son kullanılan öğesini bir değişkende tutar. Yordam, addAnotherMessage son öğeyi artırır ve yeni iletiyi depolar. Bu iki işlem ve End SyncLock deyimleri tarafından SyncLock korunur, çünkü son öğe artırıldıktan sonra, başka bir iş parçacığının son öğeyi yeniden artırabilmesi için yeni iletinin depolanması gerekir.

Sınıfı iletilerin simpleMessageList bir listesini tüm örnekleri arasında paylaştıysa, değişkenleri messagesList ve messagesLast olarak Sharedbildirilebilir. Bu durumda değişkeni messagesLock de olmalıdır Shared, böylece her örnek tarafından kullanılan tek bir kilit nesnesi olacaktır.

Kod

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

Aşağıdaki örnekte ve iş parçacıkları SyncLockkullanılır. Deyim mevcut olduğu sürece SyncLock , deyim bloğu kritik bir bölümdür ve balance hiçbir zaman negatif bir sayı olmaz. anahtar sözcüğünü SyncLock dışarıda bırakmanın etkisini görmek için ve End SyncLock deyimlerini açıklama satırı SyncLock yapabilirsiniz.

Kod

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

Açıklamalar

Ayrıca bkz.