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 veränderliche Speichervorgängen.
public ref class Volatile abstract sealed
public static class Volatile
type Volatile = class
Public Class Volatile
- Vererbung
-
Volatile
Hinweise
Auf einem Multiprozessorsystem können aufgrund von Leistungsoptimierungen im Compiler oder Prozessor normale Speichervorgänge möglicherweise neu angeordnet werden, wenn mehrere Prozessoren auf demselben Speicher arbeiten. Veränderliche Speichervorgänge verhindern bestimmte Arten der Neuanordnung im Hinblick auf den Vorgang. Durch einen veränderliche Schreibvorgang wird verhindert, dass frühere Speichervorgänge im Thread nach dem veränderliche Schreibvorgang neu angeordnet werden. Durch einen veränderlichen Lesevorgang wird verhindert, dass spätere Speichervorgänge im Thread vor dem veränderlichen Lesen neu angeordnet werden. Bei diesen Vorgängen kann es sich um Speicherbarrieren bei einigen Prozessoren handelt, 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 veränderliche Lesen und Schreiben verhindern die Neuanordnung der beiden Vorgänge innerhalb jedes Threads, z. B. vom Compiler oder vom Prozessor. Unabhängig von der Reihenfolge, in der diese Vorgänge tatsächlich auf 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 veränderliche Vorgänge, dass Thread 2 nicht angezeigt und x2 == 0nicht angezeigt y2 == 1 wird. In Thread 1 muss der Schreibvorgang x vor dem veränderliche Schreibvorgang yin auftreten, und in Thread 2 muss der Lesevorgang x nach dem veränderliche Lesevorgang yauftreten. Wenn Thread 2 also angezeigt wird y2 == 1, muss es auch angezeigt x2 == 1werden.
Berücksichtigen Sie jedoch das gleiche Szenario wie oben bei einer bestimmten Abfolge, 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 veränderliche Schreibvorgang y auf Thread 1 vor dem veränderliche Lesevorgang in y Thread 2 aufgetreten ist, wird Thread 2 möglicherweise weiterhin angezeigt y2 == 0. Der veränderliche Schreibvorgang y garantiert nicht, dass ein nachfolgendes veränderliches Lesen eines y anderen Prozessors den aktualisierten Wert anzeigt.
Note
- Veränderliche Lese- und Schreibvorgänge stellen sicher, dass ein Wert in den Arbeitsspeicher gelesen oder 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 z. B. und Double. Veränderliche Lese- und Schreibvorgänge auf einem solchen 64-Bit-Speicher sind auch bei 32-Bit-Prozessoren atomisch, im Gegensatz zu regulären Lese- und Schreibvorgängen.
Veränderliche Speichervorgänge gelten für spezielle Synchronisierungsfälle, bei denen die normale Sperrung keine akzeptable Alternative ist. Unter normalen Umständen bieten die C#-lock-Anweisung, die Visual Basic SyncLock-Anweisung 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, faulen Initialisierungscode zu schreiben, ohne die doppelgecheckte Sperre direkt zu verwenden.
Die Volatile.Read Und Volatile.Write Methoden ermöglichen Funktionen, die in Sprachen nicht unterstützt werden. Beispiel:
Einige Sprachen, z. B. Visual Basic, erkennen das Konzept von veränderliche Speichervorgängen nicht. Die Volatile Klasse stellt diese Funktionalität in solchen Sprachen bereit.
Note
Das Aufrufen einer dieser Methoden wirkt sich nur auf einen einzigen Speicherzugriff aus. Um eine effektive Synchronisierung für ein Feld bereitzustellen, muss der gesamte Zugriff auf das Feld verwendet Volatile.Read und verwendet werden Volatile.Write.
In C# garantiert die Verwendung des
volatileModifizierers für ein Feld, dass jeder Zugriff auf dieses Feld ein veränderlicher Speichervorgang ist, dervolatileModifizierer kann jedoch nicht auf Arrayelemente angewendet werden. Die Volatile.Read Methoden und Volatile.Write Methoden können für Arrayelemente verwendet werden.
Methoden
| Name | Beschreibung |
|---|---|
| Read(Boolean) |
Liest den Wert des angegebenen Felds. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn nach dieser Methode im Code ein Lese- oder Schreibzugriff angezeigt wird, kann der Prozessor ihn vor dieser Methode nicht verschieben. |
| Read(Byte) |
Liest den Wert des angegebenen Felds. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn nach dieser Methode im Code ein Lese- oder Schreibzugriff angezeigt wird, kann der Prozessor ihn vor dieser Methode nicht verschieben. |
| Read(Double) |
Liest den Wert des angegebenen Felds. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn nach dieser Methode im Code ein Lese- oder Schreibzugriff angezeigt wird, kann der Prozessor ihn vor dieser Methode nicht verschieben. |
| Read(Int16) |
Liest den Wert des angegebenen Felds. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn nach dieser Methode im Code ein Lese- oder Schreibzugriff angezeigt wird, kann der Prozessor ihn vor dieser Methode nicht verschieben. |
| Read(Int32) |
Liest den Wert des angegebenen Felds. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn nach dieser Methode im Code ein Lese- oder Schreibzugriff angezeigt wird, kann der Prozessor ihn vor dieser Methode nicht verschieben. |
| Read(Int64) |
Liest den Wert des angegebenen Felds. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn nach dieser Methode im Code ein Lese- oder Schreibzugriff angezeigt wird, kann der Prozessor ihn vor dieser Methode nicht verschieben. |
| Read(IntPtr) |
Liest den Wert des angegebenen Felds. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn nach dieser Methode im Code ein Lese- oder Schreibzugriff angezeigt wird, kann der Prozessor ihn vor dieser Methode nicht verschieben. |
| Read(SByte) |
Liest den Wert des angegebenen Felds. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn nach dieser Methode im Code ein Lese- oder Schreibzugriff angezeigt wird, kann der Prozessor ihn vor dieser Methode nicht verschieben. |
| Read(Single) |
Liest den Wert des angegebenen Felds. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn nach dieser Methode im Code ein Lese- oder Schreibzugriff angezeigt wird, kann der Prozessor ihn vor dieser Methode nicht verschieben. |
| Read(UInt16) |
Liest den Wert des angegebenen Felds. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn nach dieser Methode im Code ein Lese- oder Schreibzugriff angezeigt wird, kann der Prozessor ihn vor dieser Methode nicht verschieben. |
| Read(UInt32) |
Liest den Wert des angegebenen Felds. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn nach dieser Methode im Code ein Lese- oder Schreibzugriff angezeigt wird, kann der Prozessor ihn vor dieser Methode nicht verschieben. |
| Read(UInt64) |
Liest den Wert des angegebenen Felds. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn nach dieser Methode im Code ein Lese- oder Schreibzugriff angezeigt wird, kann der Prozessor ihn vor dieser Methode nicht verschieben. |
| Read(UIntPtr) |
Liest den Wert des angegebenen Felds. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn nach dieser Methode im Code ein Lese- oder Schreibzugriff angezeigt wird, kann der Prozessor ihn vor dieser Methode nicht verschieben. |
| Read<T>(T) |
Liest den Objektverweis aus dem angegebenen Feld. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn nach dieser Methode im Code ein Lese- oder Schreibzugriff angezeigt wird, kann der Prozessor ihn vor dieser Methode nicht verschieben. |
| Write(Boolean, Boolean) |
Schreibt den angegebenen Wert in das angegebene Feld. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn vor dieser Methode ein Lese- oder Schreibzugriff vor dieser Methode angezeigt wird, kann der Prozessor ihn nach dieser Methode nicht verschieben. |
| Write(Byte, Byte) |
Schreibt den angegebenen Wert in das angegebene Feld. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn vor dieser Methode ein Lese- oder Schreibzugriff vor dieser Methode angezeigt wird, kann der Prozessor ihn nach dieser Methode nicht verschieben. |
| Write(Double, Double) |
Schreibt den angegebenen Wert in das angegebene Feld. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn vor dieser Methode ein Lese- oder Schreibzugriff vor dieser Methode angezeigt wird, kann der Prozessor ihn nach dieser Methode nicht verschieben. |
| Write(Int16, Int16) |
Schreibt den angegebenen Wert in das angegebene Feld. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn vor dieser Methode ein Lese- oder Schreibzugriff vor dieser Methode angezeigt wird, kann der Prozessor ihn nach dieser Methode nicht verschieben. |
| Write(Int32, Int32) |
Schreibt den angegebenen Wert in das angegebene Feld. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn vor dieser Methode ein Lese- oder Schreibzugriff vor dieser Methode angezeigt wird, kann der Prozessor ihn nach dieser Methode nicht verschieben. |
| Write(Int64, Int64) |
Schreibt den angegebenen Wert in das angegebene Feld. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn vor dieser Methode ein Lese- oder Schreibzugriff vor dieser Methode angezeigt wird, kann der Prozessor ihn nach dieser Methode nicht verschieben. |
| Write(IntPtr, IntPtr) |
Schreibt den angegebenen Wert in das angegebene Feld. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn vor dieser Methode ein Lese- oder Schreibzugriff vor dieser Methode angezeigt wird, kann der Prozessor ihn nach dieser Methode nicht verschieben. |
| Write(SByte, SByte) |
Schreibt den angegebenen Wert in das angegebene Feld. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn vor dieser Methode ein Lese- oder Schreibzugriff vor dieser Methode angezeigt wird, kann der Prozessor ihn nach dieser Methode nicht verschieben. |
| Write(Single, Single) |
Schreibt den angegebenen Wert in das angegebene Feld. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn vor dieser Methode ein Lese- oder Schreibzugriff vor dieser Methode angezeigt wird, kann der Prozessor ihn nach dieser Methode nicht verschieben. |
| Write(UInt16, UInt16) |
Schreibt den angegebenen Wert in das angegebene Feld. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn vor dieser Methode ein Lese- oder Schreibzugriff vor dieser Methode angezeigt wird, kann der Prozessor ihn nach dieser Methode nicht verschieben. |
| Write(UInt32, UInt32) |
Schreibt den angegebenen Wert in das angegebene Feld. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn vor dieser Methode ein Lese- oder Schreibzugriff vor dieser Methode angezeigt wird, kann der Prozessor ihn nach dieser Methode nicht verschieben. |
| Write(UInt64, UInt64) |
Schreibt den angegebenen Wert in das angegebene Feld. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn vor dieser Methode ein Lese- oder Schreibzugriff vor dieser Methode angezeigt wird, kann der Prozessor ihn nach dieser Methode nicht verschieben. |
| Write(UIntPtr, UIntPtr) |
Schreibt den angegebenen Wert in das angegebene Feld. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn vor dieser Methode ein Lese- oder Schreibzugriff vor dieser Methode angezeigt wird, kann der Prozessor ihn nach dieser Methode nicht verschieben. |
| Write<T>(T, T) |
Schreibt den angegebenen Objektverweis auf das angegebene Feld. Fügt auf Systemen, die dies erfordern, eine Speicherbarriere ein, die verhindert, dass der Prozessor Speichervorgänge wie folgt neu anordnen kann: Wenn vor dieser Methode ein Lese- oder Schreibzugriff vor dieser Methode angezeigt wird, kann der Prozessor ihn nach dieser Methode nicht verschieben. |