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
olamazNothing
. Bir deyimdeSyncLock
kullanmadan önce lock nesnesini oluşturmanız gerekir.Bir
SyncLock
bloğu yürütürken değerinilockobject
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, ifadeyilockobject
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ığı deyimineSyncLock
ulaştığında, ilk iş parçacığı deyimini yürüteneEnd 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ürkenSyncLock
yürütmesini engeller. Bu, tüm örnekler arasında paylaşılan verileri korur.Bir örnek değişkeniyse
lockobject
(değilShared
), 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ütmesiniSyncLock
engeller. Bu, tek tek örnek tarafından tutulan verileri korur.Edinme ve Serbest Bırakma. Blok
SyncLock
, bloğun özel birTry...Finally
kilitlockobject
aldığı ve bloğunTry
Finally
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ı. blok
SyncLock
, ad alanında sınıfının System.Threading ve yöntemleriniMonitor
çağırarakEnter
özel kilidi alır veExit
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 Shared
bildirilebilir. 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ı SyncLock
kullanı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