Volatile 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.
Enthält Methoden zum Ausführen von flüchtigen Speichervorgängen.
public ref class Volatile abstract sealed
public static class Volatile
type Volatile = class
Public Class Volatile
- Vererbung
-
Volatile
Hinweise
Auf einem Multiprozessorsystem werden reguläre Arbeitsspeichervorgänge aufgrund von Leistungsoptimierungen im Compiler oder Prozessor möglicherweise neu angeordnet, wenn mehrere Prozessoren auf demselben Arbeitsspeicher arbeiten. Flüchtige Speichervorgänge verhindern bestimmte Arten der Neuanordnung in Bezug auf den Vorgang. Ein flüchtiger Schreibvorgang verhindert, dass frühere Arbeitsspeichervorgänge im Thread nach dem flüchtigen Schreibvorgang neu angeordnet werden. Ein flüchtiger Lesevorgang verhindert, dass spätere Speichervorgänge im Thread vor dem flüchtigen Lesevorgang neu angeordnet werden. Diese Vorgänge können Speicherbarrieren auf einigen Prozessoren beinhalten, die sich auf die Leistung auswirken können.
Betrachten Sie beispielsweise das folgende Szenario mit zwei Threads und zwei Int32 Feldern x
, die y
anfangs null sind:
Thread 1 | Thread 2 |
---|---|
x = 1; |
int y2 = Volatile.Read(ref y); |
Volatile.Write(ref y, 1); |
int x2 = x; |
Das flüchtige Lesen und Schreiben verhindert eine Neuanordnung der beiden Vorgänge in jedem Thread, z. B. durch den Compiler oder durch den Prozessor. Unabhängig von der Reihenfolge, in der diese Vorgänge tatsächlich in einem Thread relativ zum anderen Thread auftreten, auch auf einem Multiprozessorsystem, in dem die Threads auf verschiedenen Prozessoren ausgeführt werden können, garantieren die flüchtigen Vorgänge, dass Thread 2 und x2 == 0
nicht sehen y2 == 1
würde. In Thread 1 muss der Schreibvorgang x
vor dem flüchtigen Schreibvorgang y
in auftreten, und in Thread 2 muss das Lesen von x
nach dem flüchtigen Lesen von y
auftreten. Wenn Thread 2 also sieht y2 == 1
, muss er auch sehen x2 == 1
.
Betrachten Sie jedoch dasselbe Szenario wie oben mit einer bestimmten Sequenz, in der die Vorgänge auftreten:
Sequenz | Thread 1 | Thread 2 |
---|---|---|
1 | x = 1; |
... |
2 | Volatile.Write(ref y, 1); |
... |
3 | ... |
int y2 = Volatile.Read(ref y); |
4 | ... |
int x2 = x; |
Obwohl der flüchtige Schreibvorgang auf y
Thread 1 vor dem flüchtigen Lesen von y
in Thread 2 erfolgt ist, wird in Thread 2 möglicherweise immer noch angezeigt y2 == 0
. Der flüchtige Schreibvorgang in y
garantiert nicht, dass bei einem folgenden flüchtigen Lesevorgang von y
auf einem anderen Prozessor der aktualisierte Wert angezeigt wird.
Hinweis
- Flüchtige Lese- und Schreibvorgänge stellen sicher, dass ein Wert gelesen oder in den Arbeitsspeicher geschrieben und nicht zwischengespeichert wird (z. B. in einem Prozessorregister). Daher können Sie diese Vorgänge verwenden, um den Zugriff auf ein Feld zu synchronisieren, das von einem anderen Thread oder von Hardware aktualisiert werden kann.
- Die Volatile -Klasse bietet auch Lese- und Schreibvorgänge für einige 64-Bit-Typen wie Int64 und Double. Flüchtige Lese- und Schreibvorgänge auf einem solchen 64-Bit-Speicher sind selbst auf 32-Bit-Prozessoren unteilbar, im Gegensatz zu regulären Lese- und Schreibvorgängen.
Flüchtige Speichervorgänge sind für spezielle Synchronisierungsfälle vorgesehen, bei denen normale Sperren keine akzeptable Alternative sind. Unter normalen Umständen bieten die C#- lock
Anweisung, die Visual Basic-Anweisung SyncLock
und die Monitor -Klasse die einfachste und am wenigsten fehleranfällige Methode zum Synchronisieren des Zugriffs auf Daten, und die Lazy<T> -Klasse bietet eine einfache Möglichkeit zum Schreiben von verzögertem Initialisierungscode ohne direkte Verwendung doppelt überprüfter Sperren.
Die Volatile.Read Methoden und Volatile.Write ermöglichen Funktionen, die in Sprachen nicht unterstützt werden. Beispiel:
Einige Sprachen, z. B. Visual Basic, erkennen das Konzept von vorgängen flüchtigem Arbeitsspeicher nicht. Die Volatile -Klasse stellt diese Funktionalität in solchen Sprachen bereit.
Hinweis
Das Aufrufen einer dieser Methoden wirkt sich nur auf einen einzelnen Speicherzugriff aus. Um eine effektive Synchronisierung für ein Feld bereitzustellen, muss für den gesamten Zugriff auf das Feld und Volatile.Writeverwendet Volatile.Read werden.
In C# garantiert die Verwendung des
volatile
Modifizierers für ein Feld, dass jeder Zugriff auf dieses Feld ein flüchtiger Speichervorgang ist, dervolatile
Modifizierer kann jedoch nicht auf Arrayelemente angewendet werden. Die Volatile.Read Methoden und Volatile.Write können für Arrayelemente verwendet werden.
Methoden
Read(Boolean) |
Liest den Wert des angegebenen Felds. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn nach dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht vor diese Methode verschoben werden. |
Read(Byte) |
Liest den Wert des angegebenen Felds. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn nach dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht vor diese Methode verschoben werden. |
Read(Double) |
Liest den Wert des angegebenen Felds. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn nach dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht vor diese Methode verschoben werden. |
Read(Int16) |
Liest den Wert des angegebenen Felds. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn nach dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht vor diese Methode verschoben werden. |
Read(Int32) |
Liest den Wert des angegebenen Felds. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn nach dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht vor diese Methode verschoben werden. |
Read(Int64) |
Liest den Wert des angegebenen Felds. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn nach dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht vor diese Methode verschoben werden. |
Read(IntPtr) |
Liest den Wert des angegebenen Felds. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn nach dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht vor diese Methode verschoben werden. |
Read(SByte) |
Liest den Wert des angegebenen Felds. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn nach dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht vor diese Methode verschoben werden. |
Read(Single) |
Liest den Wert des angegebenen Felds. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn nach dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht vor diese Methode verschoben werden. |
Read(UInt16) |
Liest den Wert des angegebenen Felds. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn nach dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht vor diese Methode verschoben werden. |
Read(UInt32) |
Liest den Wert des angegebenen Felds. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn nach dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht vor diese Methode verschoben werden. |
Read(UInt64) |
Liest den Wert des angegebenen Felds. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn nach dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht vor diese Methode verschoben werden. |
Read(UIntPtr) |
Liest den Wert des angegebenen Felds. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn nach dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht vor diese Methode verschoben werden. |
Read<T>(T) |
Liest den Objektverweis aus dem angegebenen Feld. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn nach dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht vor diese Methode verschoben werden. |
Write(Boolean, Boolean) |
Schreibt den angegebenen Wert in das angegebene Feld. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn vor dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht hinter diese Methode verschoben werden. |
Write(Byte, Byte) |
Schreibt den angegebenen Wert in das angegebene Feld. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn vor dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht hinter diese Methode verschoben werden. |
Write(Double, Double) |
Schreibt den angegebenen Wert in das angegebene Feld. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn vor dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht hinter diese Methode verschoben werden. |
Write(Int16, Int16) |
Schreibt den angegebenen Wert in das angegebene Feld. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn vor dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht hinter diese Methode verschoben werden. |
Write(Int32, Int32) |
Schreibt den angegebenen Wert in das angegebene Feld. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn vor dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht hinter diese Methode verschoben werden. |
Write(Int64, Int64) |
Schreibt den angegebenen Wert in das angegebene Feld. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn vor dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht hinter diese Methode verschoben werden. |
Write(IntPtr, IntPtr) |
Schreibt den angegebenen Wert in das angegebene Feld. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn vor dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht hinter diese Methode verschoben werden. |
Write(SByte, SByte) |
Schreibt den angegebenen Wert in das angegebene Feld. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn vor dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht hinter diese Methode verschoben werden. |
Write(Single, Single) |
Schreibt den angegebenen Wert in das angegebene Feld. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn vor dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht hinter diese Methode verschoben werden. |
Write(UInt16, UInt16) |
Schreibt den angegebenen Wert in das angegebene Feld. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn vor dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht hinter diese Methode verschoben werden. |
Write(UInt32, UInt32) |
Schreibt den angegebenen Wert in das angegebene Feld. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn vor dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht hinter diese Methode verschoben werden. |
Write(UInt64, UInt64) |
Schreibt den angegebenen Wert in das angegebene Feld. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn vor dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht hinter diese Methode verschoben werden. |
Write(UIntPtr, UIntPtr) |
Schreibt den angegebenen Wert in das angegebene Feld. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn vor dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht hinter diese Methode verschoben werden. |
Write<T>(T, T) |
Schreibt den angegebenen Objektverweis in das angegebene Feld. Auf Systemen, auf denen dies erforderlich ist, wird eine Arbeitsspeicherbarriere eingefügt, die verhindert, dass der Prozessor Arbeitsspeichervorgänge wie folgt neu anordnet: Wenn vor dieser Methode im Code ein Lese- oder Schreibvorgang ausgeführt wird, kann dieser vom Prozessor nicht hinter diese Methode verschoben werden. |