Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Wenn mehrere Threads Aufrufe an die Eigenschaften und Methoden eines einzelnen Objekts ausführen können, ist es wichtig, dass diese Aufrufe synchronisiert werden. Andernfalls kann ein Thread unterbrechen, was ein anderer Thread tut, und das Objekt könnte in einem ungültigen Zustand verbleiben. Eine Klasse, deren Member vor solchen Unterbrechungen geschützt sind, wird als threadsicher bezeichnet.
.NET bietet mehrere Strategien zum Synchronisieren des Zugriffs auf Instanzen und statische Member:
Synchronisierte Codebereiche. Sie können die Monitor Klassen- oder Compilerunterstützung für diese Klasse verwenden, um nur den Codeblock zu synchronisieren, der sie benötigt, um die Leistung zu verbessern.
Manuelle Synchronisierung. Sie können die von der .NET Klassenbibliothek bereitgestellten Synchronisierungsobjekte verwenden. Siehe Übersicht über Synchronisierungsgrundtypen, die eine Diskussion über die Monitor Klasse enthalten.
Synchronisierte Kontexte. Nur für .NET Framework-Anwendungen können Sie SynchronizationAttribute verwenden, um die einfache, automatische Synchronisierung für ContextBoundObject-Objekte zu aktivieren.
Sammlungsklassen im System.Collections.Concurrent Namespace. Diese Klassen stellen integrierte synchronisierte Add- und Remove-Vorgänge bereit. Weitere Informationen finden Sie unter Thread-Safe Sammlungen.
Die Common Language Runtime stellt ein Threadmodell bereit, in dem Klassen in eine Reihe von Kategorien fallen, die je nach Den Anforderungen auf unterschiedliche Weise synchronisiert werden können. Die folgende Tabelle zeigt, welche Synchronisierungsunterstützung für Felder und Methoden mit einer bestimmten Synchronisierungskategorie bereitgestellt wird.
| Category | Globale Felder | Statische Felder | Statische Methoden | Instanzfelder | Instanzmethoden | Bestimmte Codeblöcke |
|---|---|---|---|---|---|---|
| Keine Synchronisierung | No | No | No | No | No | No |
| Synchronisierter Kontext | No | No | No | Ja | Ja | No |
| Synchronisierte Codebereiche | No | No | Nur, wenn sie markiert sind | No | Nur, wenn sie markiert sind | Nur, wenn sie markiert sind |
| Manuelle Synchronisierung | Manual | Manual | Manual | Manual | Manual | Manual |
Keine Synchronisation
Dies ist die Standardeinstellung für Objekte. Jeder Thread kann jederzeit auf eine beliebige Methode oder jedes Feld zugreifen. Nur jeweils ein Thread sollte auf diese Objekte zugreifen.
Manuelle Synchronisierung
Die .NET Klassenbibliothek stellt eine Reihe von Klassen zum Synchronisieren von Threads bereit. Siehe Übersicht über Synchronisierungsgrundtypen.
Synchronisierte Codebereiche
Sie können die Monitor Klasse oder ein Compilerschlüsselwort verwenden, um Codeblöcke, Instanzmethoden und statische Methoden zu synchronisieren. Es gibt keine Unterstützung für synchronisierte statische Felder.
Sowohl Visual Basic als auch C# unterstützen die Markierung von Codeblöcken mit einem bestimmten Sprachschlüsselwort, der lock Anweisung in C# oder der SyncLock Anweisung in Visual Basic. Wenn der Code von einem Thread ausgeführt wird, wird versucht, die Sperre abzurufen. Wenn die Sperre bereits von einem anderen Thread abgerufen wurde, blockiert der Thread, bis die Sperre verfügbar ist. Wenn der Thread den synchronisierten Codeblock verlässt, wird die Sperre freigegeben, unabhängig davon, wie der Thread den Block verlässt.
Note
In .NET 9 und C# 13 oder höher verwendet die lock-Anweisung Lock.EnterScope(), um einen synchronisierten Bereich zu erstellen, wenn das lock-Ziel eine dedizierte System.Threading.Lock-Instanz ist.
Visual Basic unterstützt System.Threading.Lock in SyncLock nicht, verwenden Sie daher weiterhin SyncLock mit einem dedizierten privaten Verweistyp.
Wenn das lock Ziel keine Lock-Instanz ist, verwendet der Compiler bei jeder Verwendung von SyncLockMonitor.Enter und Monitor.Exit. Aufgrund dieser Implementierung können Sie weiterhin andere Monitor Methoden in der synchronisierten Region verwenden.
Sie können eine Methode auch mit einem MethodImplAttribute mit dem Wert MethodImplOptions.Synchronized versehen, was denselben Effekt hat wie die Verwendung von Monitor oder einem der Compilerschlüsselwörter, um den gesamten Methodenrumpf zu sperren.
Thread.Interrupt kann verwendet werden, um einen Thread aus blockierenden Vorgängen herauszuholen, etwa beim Warten auf den Zugriff auf einen synchronisierten Codebereich. Thread.Interrupt wird auch verwendet, um Threads aus Operationen wie Thread.Sleep herauszuholen.
Von Bedeutung
Sperren Sie den Typ nicht — das heißt typeof(MyType) in C#, GetType(MyType) in Visual Basic oder MyType::typeid in C++ —, um static-Methoden zu schützen (Shared-Methoden in Visual Basic). Verwenden Sie stattdessen ein privates statisches Objekt. Verwenden Sie auch nicht this in C# (Me in Visual Basic), um Instanzmethoden zu sperren. Verwenden Sie stattdessen ein privates Objekt. Eine Klasse oder Instanz kann von einem anderen Code als Ihrem eigenen gesperrt werden, was möglicherweise zu Deadlocks oder Leistungsproblemen führt.
Compilerunterstützung
Sowohl Visual Basic als auch C# unterstützen ein Schlüsselwort, das Monitor.Enter und Monitor.Exit verwendet, um das Objekt zu sperren. Visual Basic unterstützt die SyncLock-Anweisung; C# unterstützt die Lock-Anweisung.
Wenn in beiden Fällen im Codeblock eine Ausnahme ausgelöst wird, wird die durch lock oder SyncLock erworbene Sperre automatisch freigegeben. Die Compiler für C# und Visual Basic generieren einen try/finally-Block mit Monitor.Enter zu Beginn des try-Blocks und Monitor.Exit im finally-Block. Wenn eine Ausnahme innerhalb eines lock- oder SyncLock-Blocks ausgelöst wird, wird der finally-Handler ausgeführt, damit Sie notwendige Bereinigungen ausführen können.
Synchronisierter Kontext
Nur in .NET Framework-Anwendungen können Sie das SynchronizationAttribute für jedes ContextBoundObject verwenden, um alle Instanzmethoden und -felder zu synchronisieren. Alle Objekte in derselben Kontextdomäne verwenden dieselbe Sperre. Mehrere Threads dürfen auf die Methoden und Felder zugreifen, aber es ist jeweils nur ein einzelner Thread zulässig.