Lock Klasse
Definition
Wichtig
Einige Informationen beziehen sich auf Vorabversionen, die vor dem Release ggf. grundlegend überarbeitet werden. Microsoft übernimmt hinsichtlich der hier bereitgestellten Informationen keine Gewährleistungen, seien sie ausdrücklich oder konkludent.
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 keinawait
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 Exit
haben. 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.Lock
sein. 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 Lock
gehalten 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. |