Sdílet prostřednictvím


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

3a86s51t.collapse_all(cs-cz,VS.110).gifDescription

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.

3a86s51t.collapse_all(cs-cz,VS.110).gifKó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

3a86s51t.collapse_all(cs-cz,VS.110).gifDescription

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.

3a86s51t.collapse_all(cs-cz,VS.110).gifKó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

System.Threading

Monitor

Podproces synchronizace (C# a Visual Basic)

Další zdroje

Zřetězení (C# a Visual Basic)