Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
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çalar
lockobject
Gerekli. Nesne başvurusu olarak değerlendirilen ifade.
block
Opsiyonel. 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
SyncLockbloğa dallanamaz.Nesne Değerini Kilitle. değeri
lockobjectolamazNothing. Bir deyimdeSyncLockkullanmadan önce lock nesnesini oluşturmanız gerekir.Bir
SyncLockbloğu yürütürken değerinilockobjectdeğiştiremezsiniz. Mekanizma, kilit nesnesinin değişmeden kalmasını gerektirir.Bir blokta
SyncLockAwait işlecini kullanamazsınız.
Davranış
Mekanizma. bir iş parçacığı deyimine
SyncLockulaştığında, ifadeyilockobjectdeğ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ığı deyimineSyncLockulaştığında, ilk iş parçacığı deyimini yürüteneEnd SyncLockkadar kilit almaz.Korumalı Veriler. Bir
Shareddeğ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ürkenSyncLockyü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ütmesiniSyncLockengeller. Bu, tek tek örnek tarafından tutulan verileri korur.Edinme ve Serbest Bırakma. Blok
SyncLock, bloğun özel birTry...Finallykilitlockobjectaldığı ve bloğunTryFinallyonu serbest bıraktığı bir yapı gibi davranır. Bu nedenle blok,SyncLockblok 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 veExitserbest 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
Açıklama
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