Freigeben über


Lock Klasse

Definition

Hinweis

Um diese Vorschau-API zu verwenden, müssen Sie Previewfunktionen in Ihrem Projekt aktivieren, indem Sie die Eigenschaft EnablePreviewFeatures in Ihrer Projektdatei auf True festlegen. Weitere Informationen findest du unter https://aka.ms/dotnet-preview-features.

Stellt einen Mechanismus zum erreichen gegenseitigen Ausschluss in Codebereichen zwischen verschiedenen Threads bereit.

public ref class Lock sealed
[System.Runtime.Versioning.RequiresPreviewFeatures]
public sealed class Lock
[<System.Runtime.Versioning.RequiresPreviewFeatures>]
type Lock = class
Public NotInheritable Class Lock
Vererbung
Lock
Attribute

Hinweise

Die Lock -Klasse kann verwendet werden, um Codebereiche zu definieren, die sich gegenseitig ausschließenden Zugriff zwischen Threads eines Prozesses erfordern, die häufig als kritische Abschnitte bezeichnet werden, um gleichzeitige Zugriffe auf eine Ressource zu verhindern. Ein Lock kann eingegeben und beendet werden, wobei der Codebereich zwischen der Eingabe und dem Beenden ein kritischer Abschnitt ist, der der Sperre zugeordnet ist. Ein Thread, der in eine Sperre eintritt, soll die Sperre halten oder besitzen, bis die Sperre beendet wird. Höchstens ein Thread kann zu einem bestimmten Zeitpunkt eine Sperre halten. Ein Thread kann mehrere Sperren enthalten. Ein Thread kann mehrere Male in eine Sperre eintreten, bevor er beendet wird, z. B. rekursiv. Ein Thread, der nicht sofort in eine Sperre gelangen kann, kann warten, bis die Sperre eingegeben werden kann oder bis ein angegebenes Timeout abläuft.

Wenn Sie die Enter -Methode oder TryEnter verwenden, um eine Sperre einzugeben:

  • Stellen Sie sicher, dass der Thread die Sperre Exit auch bei Ausnahmen beendet, z. B. in C# mithilfe eines try/finally -Blocks.
  • Wenn die Sperre in einer C#- async Methode eingegeben und beendet wird, stellen Sie sicher, dass zwischen enter und exit kein await Wert vorhanden ist. Sperren werden von Threads gehalten, und der Code, der auf einen folgt, await kann in einem anderen Thread ausgeführt werden.

Es wird empfohlen, die EnterScope -Methode mit einem Sprachkonstrukt zu verwenden, das das zurückgegebene Lock.Scope automatisch verwird, z. B. die C#- using Schlüsselwort (keyword), oder die C#- lock Schlüsselwort (keyword) zu verwenden, da dadurch sichergestellt wird, dass die Sperre in Ausnahmefällen beendet wird. Diese Muster können auch Leistungsvorteile gegenüber der Verwendung von Enter/TryEnter und Exithaben. Das folgende Codefragment veranschaulicht verschiedene Muster zum Eingeben und Beenden einer Sperre.

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

Wenn Sie die C#- lock Schlüsselwort (keyword) oder ähnlich zum Eingeben und Beenden einer Sperre verwenden, muss der Typ des Ausdrucks genau System.Threading.Locksein. Wenn der Typ des Ausdrucks ein anderer ist, z Object . B. oder ein generischer Typ wie T, kann stattdessen eine andere Implementierung verwendet werden, die nicht austauschbar ist (z Monitor. B. ). Weitere Informationen finden Sie im entsprechenden Compilerspezlet.

Interrupt kann Threads unterbrechen, die auf den Eintritt in eine Sperre warten. Bei Windows STA-Threads ermöglicht das Warten auf Sperren das Pumpen von Nachrichten, die während einer Wartezeit anderen Code im selben Thread ausführen können. Einige Features der Wartevorgänge können von einem benutzerdefinierten SynchronizationContextüberschrieben werden.

Hinweis

Ein Thread, der in eine Sperre eintritt( z. B. rekursiv mehrmals), muss die Sperre genauso oft beenden, um die Sperre vollständig zu beenden und anderen Threads den Zugriff auf die Sperre zu gestatten. Wenn ein Thread beendet wird, während ein Lockgehalten wird, wird das Verhalten von Lock undefiniert.

Achtung

Wenn ein Thread in einem Codepfad möglicherweise mehrere Sperren eingibt, bevor er sie beendet, stellen Sie sicher, dass alle Codepfade, die möglicherweise zwei dieser Sperren für denselben Thread eingeben, sie in derselben Reihenfolge eingeben. Andernfalls könnte dies zu Deadlocks führen. Stellen Sie sich beispielsweise vor, dass in einem Codepfadthread T1 die Sperre L1 und dann die Sperre L2 eintritt, bevor beide beendet werden, und in einem anderen Codepfadthread T2 beide Sperren in umgekehrter Reihenfolge eingibt. In diesem Szenario wäre es möglich, dass die folgende Reihenfolge der Ereignisse eintritt: T1 gibt ein L1, T2 gibt ein L2, versucht, T1 einzugeben L2 und wartet, versucht, T2 einzugeben L1 und wartet. Es gibt einen Deadlock zwischen T1 und T2 , der nicht aufgelöst werden kann, und alle anderen Threads, die in Zukunft versuchen, eine Sperre zu betreten, bleiben ebenfalls hängen.

Konstruktoren

Lock()

Initialisiert eine neue Instanz der Lock-Klasse.

Eigenschaften

IsHeldByCurrentThread

Ruft einen Wert ab, der angibt, ob die Sperre vom aktuellen Thread gehalten wird.

Methoden

Enter()

Tritt in die Sperre ein und wartet bei Bedarf, bis die Sperre betreten werden kann.

EnterScope()

Tritt in die Sperre ein und wartet bei Bedarf, bis die Sperre betreten werden kann.

Equals(Object)

Bestimmt, ob das angegebene Objekt gleich dem aktuellen Objekt ist.

(Geerbt von Object)
Exit()

Beendet die Sperre.

GetHashCode()

Fungiert als Standardhashfunktion.

(Geerbt von Object)
GetType()

Ruft den Type der aktuellen Instanz ab.

(Geerbt von Object)
MemberwiseClone()

Erstellt eine flache Kopie des aktuellen Object.

(Geerbt von Object)
ToString()

Gibt eine Zeichenfolge zurück, die das aktuelle Objekt darstellt.

(Geerbt von Object)
TryEnter()

Versucht, die Sperre zu betreten, ohne zu warten.

TryEnter(Int32)

Versucht, die Sperre zu betreten, und wartet bei Bedarf auf die angegebene Anzahl von Millisekunden, bis die Sperre eingegeben werden kann.

TryEnter(TimeSpan)

Versucht, die Sperre zu betreten, und wartet bei Bedarf, bis die Sperre eingegeben werden kann oder bis das angegebene Timeout abläuft.

Gilt für: