Sdílet prostřednictvím


Lock Třída

Definice

Poznámka

Pokud chcete toto rozhraní API verze Preview používat, musíte ve svém projektu povolit funkce Preview, a to nastavením vlastnosti EnablePreviewFeatures na True v souboru projektu. Další informace najdete na webu https://aka.ms/dotnet-preview-features.

Poskytuje mechanismus pro dosažení vzájemného vyloučení v oblastech kódu mezi různými vlákny.

public ref class Lock sealed
[System.Runtime.Versioning.RequiresPreviewFeatures]
public sealed class Lock
[<System.Runtime.Versioning.RequiresPreviewFeatures>]
type Lock = class
Public NotInheritable Class Lock
Dědičnost
Lock
Atributy

Poznámky

Třída Lock se dá použít k definování oblastí kódu, které vyžadují vzájemně se vylučující přístup mezi vlákny procesu, běžně označovanými jako kritické oddíly, aby se zabránilo souběžnému přístupu k prostředku. Lze Lock zadat a ukončit, kde oblast kódu mezi vstupem a výstupem je kritickou částí přidruženou k zámku. Vlákno, které vstupuje do zámku, se říká, že zámek drží nebo vlastní, dokud zámek opustí. Maximálně jedno vlákno může mít v daném okamžiku zámek. Vlákno může obsahovat více zámků. Vlákno může před ukončením několikrát zadat zámek, například rekurzivně. Vlákno, které nemůže zadat zámek okamžitě, může počkat na zadání zámku nebo na vypršení zadaného časového limitu.

Při použití Enter metody nebo TryEnter k zadání zámku:

  • Ujistěte se, že vlákno ukončí zámek Exit i v případě výjimek, jako je například v jazyce C#, pomocí try/finally bloku.
  • Když se zámek zadává a ukončuje v metodě jazyka C# async , ujistěte se, že mezi vstupem a ukončením není žádný await zámek. Zámky jsou drženy vlákny a kód následující za objektem await může běžet v jiném vlákně.

Doporučujeme použít metodu EnterScope s konstruktorem jazyka, který automaticky odstraní vrácené Lock.Scope klíčové slovo, jako je klíčové slovo C# using , nebo klíčové slovo jazyka C# lock , které zajistí, že se zámek ve výjimečných případech ukončí. Tyto vzory můžou mít oproti používání Enter/TryEnter a Exittaké výhody z hlediska výkonu. Následující fragment kódu znázorňuje různé vzory pro zadání a ukončení zámku.

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(); }
        }
    }
}

Při použití klíčového slova C# lock nebo podobného k zadání a ukončení zámku musí být typ výrazu přesně System.Threading.Lock. Pokud je typ výrazu cokoli jiného, například Object nebo obecný typ, jako Tje , můžete místo toho použít jinou implementaci, která není zaměnitelná (například Monitor). Další informace najdete v příslušné specletu kompilátoru.

Interrupt může přerušit vlákna, která čekají na zadání zámku. Ve vláknech Windows STA čekání na zámky umožňují pumpování zpráv, které mohou během čekání spustit jiný kód ve stejném vlákně. Některé funkce čekání lze přepsat vlastním SynchronizationContext.

Poznámka

Vlákno, které vstupuje do zámku, včetně vícekrát, například rekurzivně, musí zámek opustit stejný početkrát, aby se zámek úplně ukončil a umožnilo ostatním vláknům vstoupit do zámku. Pokud vlákno opustí při držení Lock, chování objektu Lock se nedefinuje.

Upozornění

Pokud v cestě ke kódu může vlákno zadat více zámků před jejich ukončením, ujistěte se, že všechny cesty kódu, které by mohly zadat jakékoli dva z těchto zámků ve stejném vlákně, je zadávají ve stejném pořadí. Jinak by to mohlo vést ke vzájemným zablokováním. Představte si například, že na jednom podprocesu T1 cesty kódu zadá zámek L1 a pak zámek L2 před ukončením obou a na jiném podproces T2 cesty kódu zadá oba zámky v inverzním pořadí. V takovém scénáři by mohlo dojít k následujícímu pořadí událostí: zadá , zadá , pokusí se zadat L2 a počká, T2 pokusí se zadat L1 a čeká. T1L2T2L1T1 Mezi a T2 dochází ke vzájemnému zablokováníT1, které se nedá vyřešit, a všechna další vlákna, která se v budoucnu pokusí zadat zámek, se také zablokují.

Konstruktory

Lock()

Inicializuje novou instanci Lock třídy .

Vlastnosti

IsHeldByCurrentThread

Získá hodnotu, která označuje, zda zámek je držen aktuální vlákno.

Metody

Enter()

Vloží zámek a v případě potřeby počká, až bude zámek možné zadat.

EnterScope()

Vloží zámek a v případě potřeby počká, až bude zámek možné zadat.

Equals(Object)

Určí, zda se zadaný objekt rovná aktuálnímu objektu.

(Zděděno od Object)
Exit()

Ukončí zámek.

GetHashCode()

Slouží jako výchozí hashovací funkce.

(Zděděno od Object)
GetType()

Type Získá z aktuální instance.

(Zděděno od Object)
MemberwiseClone()

Vytvoří mělkou kopii aktuálního Objectsouboru .

(Zděděno od Object)
ToString()

Vrátí řetězec, který představuje aktuální objekt.

(Zděděno od Object)
TryEnter()

Pokusí se zadat zámek bez čekání.

TryEnter(Int32)

Pokusí se zadat zámek a v případě potřeby čeká na zadaný počet milisekund, dokud zámek nebude možné zadat.

TryEnter(TimeSpan)

Pokusí se zadat zámek a v případě potřeby čeká na zadání zámku nebo na vypršení zadaného časového limitu.

Platí pro