Taal

Lock Klas

Definitie

Biedt een mechanisme voor het bereiken van wederzijdse uitsluiting in codegebieden tussen verschillende threads.

public ref class Lock sealed
public sealed class Lock
type Lock = class
Public NotInheritable Class Lock
Overname
Lock

Opmerkingen

De Lock klasse kan worden gebruikt voor het definiëren van codegebieden waarvoor wederzijds exclusieve toegang tussen threads van een proces, ook wel kritieke secties genoemd, is vereist om gelijktijdige toegang tot een resource te voorkomen. Een Lock kan worden ingevoerd en afgesloten, waarbij het codegebied tussen het invoeren en afsluiten een kritieke sectie is die aan de vergrendeling is gekoppeld. Een schroefdraad die een vergrendeling binnenkomt, wordt gezegd dat deze de vergrendeling vasthoudt of bezit totdat het slot wordt afgesloten. Maximaal één thread kan op elk gewenst moment een vergrendeling bevatten. Een thread kan meerdere vergrendelingen bevatten. Een thread kan meerdere keren een vergrendeling invoeren voordat deze wordt afgesloten, zoals recursief. Een thread die niet onmiddellijk een vergrendeling kan invoeren, kan wachten totdat de vergrendeling kan worden ingevoerd of totdat een opgegeven time-out verloopt.

Wanneer u de Enter of TryEnter methoden gebruikt om een vergrendeling in te voeren:

  • Zorg ervoor dat de thread de vergrendeling sluit, Exit zelfs in geval van uitzonderingen, zoals in C# met behulp van een try/finally blok.
  • Wanneer de vergrendeling wordt ingevoerd en afgesloten in een C# async -methode, moet u ervoor zorgen dat er geen await verbinding is tussen het invoeren en afsluiten. Vergrendelingen worden bewaard door threads en de code na een await thread kan worden uitgevoerd op een andere thread.

Het wordt aanbevolen om de EnterScope methode te gebruiken met een taalconstructie waarmee het geretourneerde trefwoord automatisch wordt verwijderd Lock.Scope , zoals het C# using -trefwoord, of om het C# lock -trefwoord te gebruiken, omdat deze ervoor zorgen dat de vergrendeling in uitzonderlijke gevallen wordt afgesloten. Deze patronen kunnen ook prestatievoordelen hebben ten opzichte van het gebruik Enter/TryEnter en Exit. Het volgende codefragment illustreert verschillende patronen voor het invoeren en afsluiten van een vergrendeling.

public sealed class ExampleDataStructure
{
    private readonly Lock _lockObj = new();

    public void Modify()
    {
        lock (_lockObj)
        {
            // Critical section associated with _lockObj
        }

        using (_lockObj.EnterScope())
        {
            // Critical section associated with _lockObj
        }

        _lockObj.Enter();
        try
        {
            // Critical section associated with _lockObj
        }
        finally { _lockObj.Exit(); }

        if (_lockObj.TryEnter())
        {
            try
            {
                // Critical section associated with _lockObj
            }
            finally { _lockObj.Exit(); }
        }
    }
}

Wanneer u het C# lock -trefwoord gebruikt of vergelijkbaar is met het invoeren en afsluiten van een vergrendeling, moet het type expressie precies System.Threading.Lockzijn. Als het type van de expressie iets anders is, zoals Object of een algemeen type, Tkan in plaats daarvan een andere implementatie worden gebruikt die niet uitwisselbaar is (zoals Monitor). Zie de relevante component in de C#-conceptstandaard voor meer informatie.

Interrupt kan threads onderbreken die wachten om een vergrendeling in te voeren. Wacht op Windows STA-threads op vergrendelingen om berichten te pompen die tijdens een wachttijd andere code op dezelfde thread kunnen uitvoeren. Sommige functies van de wachttijden kunnen worden overschreven door een aangepaste SynchronizationContext.

Note

Een thread die een vergrendeling binnenkomt, inclusief meerdere keren zoals recursief, moet de vergrendeling hetzelfde aantal keren afsluiten om de vergrendeling volledig af te sluiten en andere threads toe te staan de vergrendeling in te voeren. Als een thread wordt afgesloten terwijl een Lockthread wordt vastgehouden, wordt het gedrag van de Lock thread niet gedefinieerd.

Caution

Als een thread op een codepad meerdere vergrendelingen kan invoeren voordat deze worden afgesloten, moet u ervoor zorgen dat alle codepaden die twee van deze vergrendelingen op dezelfde thread kunnen invoeren, deze in dezelfde volgorde invoeren. Anders kan het leiden tot impasses. Houd er bijvoorbeeld rekening mee dat op de ene codepadthread T1 vergrendeling L1 wordt ingevoerd en vervolgens wordt vergrendeld L2 voordat u beide afsluit. Bij een andere codepadthread T2 worden beide vergrendelingen in de omgekeerde volgorde ingevoerd. In dat scenario is het mogelijk om de volgende volgorde van gebeurtenissen op te treden: enters , enters L2, T1 probeert in te voeren L2 en te wachten, T2 probeert in te voeren L1 en te wachten. T2L1T1 Er is een impasse tussen T1 en T2 dat kan niet worden opgelost, en andere threads die proberen om in de toekomst een vergrendeling in te voeren, hangen ook vast.

Constructors

Naam Description
Lock()

Initialiseert een nieuw exemplaar van de Lock klasse.

Eigenschappen

Naam Description
IsHeldByCurrentThread

Hiermee wordt een waarde opgehaald die aangeeft of de vergrendeling wordt vastgehouden door de huidige thread.

Methoden

Naam Description
Enter()

Voert de vergrendeling in en wacht zo nodig totdat de vergrendeling kan worden ingevoerd.

EnterScope()

Voert de vergrendeling in en wacht zo nodig totdat de vergrendeling kan worden ingevoerd.

Equals(Object)

Bepaalt of het opgegeven object gelijk is aan het huidige object.

(Overgenomen van Object)
Exit()

Sluit de vergrendeling af.

GetHashCode()

Fungeert als de standaardhashfunctie.

(Overgenomen van Object)
GetType()

Hiermee haalt u de Type huidige instantie op.

(Overgenomen van Object)
MemberwiseClone()

Hiermee maakt u een ondiepe kopie van de huidige Object.

(Overgenomen van Object)
ToString()

Retourneert een tekenreeks die het huidige object vertegenwoordigt.

(Overgenomen van Object)
TryEnter()

Probeert de vergrendeling in te gaan zonder te wachten.

TryEnter(Int32)

Probeert de vergrendeling in te voeren en wacht zo nodig voor het opgegeven aantal milliseconden totdat de vergrendeling kan worden ingevoerd.

TryEnter(TimeSpan)

Probeert de vergrendeling in te voeren en wacht zo nodig totdat de vergrendeling kan worden ingevoerd of totdat de opgegeven time-out verloopt.

Van toepassing op