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 , , , , , , , , byte a short ushort int uint char float bool .
  • Typ enum s jedním z následujících základních typů: , , , byte , nebo sbyte short ushort int uint .
  • 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#.

Viz také