volatile (Referenční dokumentace jazyka C#)
Klíčové volatile slovo označuje, že pole může být změněno více vlákny, která jsou spuštěna ve stejnou dobu. Kompilátor, systém modulu runtime a dokonce i hardware mohou kvůli výkonu měnit uspořádání čtení a zápisů do umístění v paměti. Pole, která jsou volatile deklarována, jsou vyloučena z určitých druhů optimalizací. Neexistuje žádná záruka jednoho celkového pořadí nestálých zápisů, jak je vidět ze všech vláken provádění. Další informace najdete ve třídě Volatile .
Poznámka
V multiprocesorovém systému nestálá operace čtení nezaručuje získání nejnovější hodnoty zapsané do tohoto umístění v paměti žádným procesorem. Podobně nestálá operace zápisu nezaručuje, že zapisovatá hodnota bude okamžitě viditelná pro ostatní procesory.
Klíčové volatile slovo lze použít pro pole těchto typů:
- Odkazové typy.
- Typy ukazatelů (v nezabezpečeném kontextu). Všimněte si, že ačkoli samotný ukazatel může být nestálý, objekt, na který odkazuje, nemůže. Jinými slovy nelze deklarovat "ukazatel na nestálá".
- Jednoduché typy jako
sbyte, , , , , , , ,byteashortushortintuintcharfloatbool. - Typ
enums jedním z následujících základních typů: , , ,byte, nebosbyteshortushortintuint. - Parametry obecného typu, které jsou známé jako odkazové typy.
- IntPtr a UIntPtr .
Jiné typy, včetně a , nelze označit, protože čtení a zápisy do polí těchto typů nelze zaručit jako double long volatile atomické. Chcete-li chránit vícevřetěnový přístup k te všem typům polí, použijte členy třídy nebo Interlocked chraňte přístup pomocí lock příkazu .
Klíčové volatile slovo lze použít pouze u polí nebo class struct . Místní proměnné nelze volatile deklarovat.
Příklad
Následující příklad ukazuje, jak deklarovat proměnnou veřejného pole jako volatile .
class VolatileTest
{
public volatile int sharedStorage;
public void Test(int i)
{
sharedStorage = i;
}
}
Následující příklad ukazuje, jak lze vytvořit pomocné nebo pracovní vlákno a použít ho k paralelnímu zpracování s primárním vláknem. Další informace o multithreadingu najdete v tématu Spravované threading.
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.
}
S modifikátorem přidaným do deklarace funkce získáte vždy stejné výsledky (podobně jako úryvek zobrazený volatile _shouldStop v předchozím kódu). Bez tohoto modifikátoru členu je _shouldStop ale chování nepředvídatelné. Metoda DoWork může optimalizovat přístup ke členu, což vede ke čtení zastaralých dat. Vzhledem k povaze programování s více vlákny je počet zastaralých čtení nepředvídatelný. Různá spuštění programu budou mít poněkud odlišné výsledky.
specifikace jazyka C#
Další informace najdete v tématu Specifikace jazyka C#. Specifikace jazyka je úplným a rozhodujícím zdrojem pro syntaxi a použití jazyka C#.