Příkaz SyncLock
Před provedením bloku získá výhradní zámek pro blok příkazu.
SyncLock lockobject
[ block ]
End SyncLock
Části
lockobject
Povinné.Výraz, jehož výsledkem je odkaz na objekt.block
Nepovinné.Blok příkazů, které chcete spustit, pokud je zámek získat.End SyncLock
Ukončí SyncLock bloku.
Poznámky
SyncLock Prohlášení zajišťuje, že více podprocesů nespustit blok příkazu současně.SyncLockbrání zadávání bloku, dokud žádný jiný podproces provádí každý podproces.
Nejběžnější použití SyncLock je ochrana dat před aktualizované současně více než jeden podproces.Musí-li příkazy pro manipulaci s daty dokončení bez přerušení, umístěte je uvnitř SyncLock bloku.
Příkaz blokovat chráněn výhradní zámek se někdy nazývá kritický oddíl.
Pravidla
Větvení.Nelze Nepodmíněný skok do SyncLock blokovat mimo blok.
Hodnota objektu zámku.Hodnota lockobject nemůže být Nothing.Před použitím v musíte vytvořit objekt zámku SyncLock prohlášení.
Nelze změnit hodnotu lockobject při provádění SyncLock bloku.Mechanismus vyžaduje nezmění objektu zámku.
Nelze použít Await operátor v SyncLock bloku.
Chování
Mechanismus.Když dosáhne podproces SyncLock příkaz, vyhodnocuje lockobject výraz a pozastaví provádění dokud získá výhradní zámek na objekt vrácený výraz.Když dosáhne jiným podprocesem SyncLock prohlášení ji nezískává zámek až do první podproces spuštěn End SyncLock prohlášení.
Chráněná Data.Pokud lockobject je Shared proměnné, výhradní zámek zabrání podproces v libovolné instance třídy spuštění SyncLock blokovat, zatímco jiný podproces provádí.Tím chrání data sdílená mezi všemi instancemi.
Pokud lockobject je proměnné instance (není Shared), zámek zabraňuje spuštění v aktuální instanci spuštění podprocesu SyncLock bloku současně ve stejné instanci jiný podproces.Tím chrání data spravují jednotlivé instance.
Pořízení a vydání.A SyncLock bloku se chová jako Try...Finally stavby, ve kterém Try bloku získá výhradní zámek na lockobject a Finally bloku uvolní.Z tohoto důvodu SyncLock bloku záruky uvolnění zámku, bez ohledu na to, jak ukončit blok.Toto platí i u neošetřená výjimka.
Volání v rámci.SyncLock Bloku získá a uvolní výhradní zámek voláním Enter a Exit metod Monitor třídy v System.Threading oboru názvů.
Postupy pro programování
lockobject Objekt, který patří do třídy výhradně vždy by měl být vyhodnocen výraz.By měla deklarovat Private objektové proměnné k ochraně dat náležející do aktuální instanci nebo Private Shared objektové proměnné chránit data společná pro všechny instance.
Nepoužívejte Me objektu klíčové poskytovat zámek pro instanci data.Pokud kód do třídy externí odkaz na instanci třídy, ji může tento odkaz používat jako objekt zámku pro SyncLock bloku zcela odlišné od vás, ochrana dat na jiný.Tímto způsobem do třídy a jiných může blokovat navzájem provádění jejich nesouvisející SyncLock bloky.Podobně zamykání na řetězec může být problematické, protože jiný kód procesu pomocí stejného řetězce budou sdílet stejnou zámku.
Není vhodné používat Me.GetType metodu objektu zámku pro poskytování sdílených dat.Důvodem je, že GetType vždy vrátí stejný Type objektu pro název dané třídy.Externí kód může volat GetType na třídy a získat používáte stejný objekt zámku.By výsledkem dvě třídy blokování ostatní z jejich SyncLock bloky.
Příklady
Description
Následující příklad ukazuje třídu, která udržuje seznam zpráv.V matici obsahuje zprávy a poslední prvek tohoto pole použít proměnné.addAnotherMessage Postup zvyšuje poslední prvek a ukládá nové zprávy.Jsou chráněny tyto dvě operace SyncLock a End SyncLock příkazy, protože po posledním prvkem byla zvýšena, před jiným podprocesem znovu zvýšit poslední prvek musí být uloženy nové zprávy.
Pokud simpleMessageList třídy sdílené jeden seznam zpráv mezi všechny jeho instance, proměnné messagesList a messagesLast by deklarován jako Shared.V tomto případě proměnné messagesLock by Shared, takže by jediný zámek objekt používaný každé instanci.
Kód
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
Následující příklad používá podprocesů a SyncLock.Dokud SyncLock prohlášení, prohlášení blok je kritická sekce a balance nikdy stane záporné číslo.Můžete komentovat SyncLock a End SyncLock prohlášení a vynecháním účinek SyncLock klíčové slovo.
Kód
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
Viz také
Referenční dokumentace
Podproces synchronizace (C# a Visual Basic)