vluchtig (C#-verwijzing)
Het volatile
trefwoord geeft aan dat een veld kan worden gewijzigd door meerdere threads die tegelijkertijd worden uitgevoerd. De compiler, het runtimesysteem en zelfs de hardware kunnen lees- en schrijfbewerkingen om prestatieredenen opnieuw rangschikken naar geheugenlocaties. Velden die zijn gedeclareerd volatile
, worden uitgesloten van bepaalde soorten optimalisaties. Er is geen garantie voor één totale volgorde van vluchtige schrijfbewerkingen, zoals te zien is vanuit alle threads van uitvoering. Zie de Volatile klas voor meer informatie.
Notitie
Op een multiprocessorsysteem garandeert een vluchtige leesbewerking niet dat de meest recente waarde wordt verkregen die door een processor naar die geheugenlocatie wordt geschreven. Op dezelfde manier garandeert een vluchtige schrijfbewerking niet dat de geschreven waarde onmiddellijk zichtbaar is voor andere processors.
Het volatile
trefwoord kan worden toegepast op velden van deze typen:
- Referentietypen.
- Aanwijzertypen (in een onveilige context). Houd er rekening mee dat hoewel de aanwijzer zelf vluchtig kan zijn, het object waarnaar wordt verwezen, niet kan. Met andere woorden, u kunt geen 'aanwijzer naar vluchtig' declareren.
- Eenvoudige typen zoals
sbyte
, ,byte
short
, ,ushort
,int
, ,uint
, ,char
, , , enfloat
.bool
- Een
enum
type met een van de volgende basistypen:byte
,sbyte
,short
,ushort
, , , ofint
uint
. - Algemene typeparameters die verwijzingstypen zijn.
- IntPtr en UIntPtr.
Andere typen, waaronder double
en long
, kunnen niet worden gemarkeerd volatile
omdat lees- en schrijfbewerkingen naar velden van deze typen niet kunnen worden gegarandeerd atomisch. Als u toegang met meerdere threads tot deze typen velden wilt beveiligen, gebruikt u de Interlocked klasseleden of beveiligt u de toegang met behulp van de lock
instructie.
Het volatile
trefwoord kan alleen worden toegepast op velden van een class
of struct
. Lokale variabelen kunnen niet worden gedeclareerd volatile
.
Opmerking
In het volgende voorbeeld ziet u hoe u een variabele voor een openbaar veld declareert als volatile
.
class VolatileTest
{
public volatile int sharedStorage;
public void Test(int i)
{
sharedStorage = i;
}
}
In het volgende voorbeeld ziet u hoe een hulp- of werkthread kan worden gemaakt en gebruikt om de verwerking parallel met die van de primaire thread uit te voeren. Zie Managed Threading voor meer informatie over multithreading.
public class Worker
{
// This method is called when the thread is started.
public void DoWork()
{
bool work = false;
while (!_shouldStop)
{
work = !work; // simulate some work
}
Console.WriteLine("Worker thread: terminating gracefully.");
}
public void RequestStop()
{
_shouldStop = true;
}
// Keyword volatile is used as a hint to the compiler that this data
// member is accessed by multiple threads.
private volatile bool _shouldStop;
}
public class WorkerThreadExample
{
public static void Main()
{
// Create the worker thread object. This does not start the thread.
Worker workerObject = new Worker();
Thread workerThread = new Thread(workerObject.DoWork);
// Start the worker thread.
workerThread.Start();
Console.WriteLine("Main thread: starting worker thread...");
// Loop until the worker thread activates.
while (!workerThread.IsAlive)
;
// Put the main thread to sleep for 500 milliseconds to
// allow the worker thread to do some work.
Thread.Sleep(500);
// Request that the worker thread stop itself.
workerObject.RequestStop();
// Use the Thread.Join method to block the current thread
// until the object's thread terminates.
workerThread.Join();
Console.WriteLine("Main thread: worker thread has terminated.");
}
// Sample output:
// Main thread: starting worker thread...
// Worker thread: terminating gracefully.
// Main thread: worker thread has terminated.
}
Wanneer de volatile
wijzigingsfunctie is toegevoegd aan de declaratie van _shouldStop
de module, krijgt u altijd dezelfde resultaten (vergelijkbaar met het fragment dat in de voorgaande code wordt weergegeven). Zonder die wijzigingsfunctie op het _shouldStop
lid is het gedrag echter onvoorspelbaar. De DoWork
methode kan de toegang tot leden optimaliseren, wat resulteert in het lezen van verouderde gegevens. Vanwege de aard van programmeren met meerdere threads is het aantal verlopen leesbewerkingen onvoorspelbaar. Verschillende uitvoeringen van het programma zullen enigszins verschillende resultaten opleveren.
C#-taalspecificatie
Zie de C#-taalspecificatie voor meer informatie. De taalspecificatie is de definitieve bron voor de C#-syntaxis en het gebruik.