Sdílet prostřednictvím


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á se spouští současně. Kompilátor, systém runtime a dokonce i hardware může změnit uspořádání čtení a zápisů do umístění paměti z důvodu výkonu. Deklarovaná pole jsou vyloučena volatile 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 v předmětu Volatile .

Poznámka:

V multiprocesorovém systému nestálá operace čtení nezaručuje získání nejnovější hodnoty zapsané do umístění paměti jakýmkoli procesorem. Podobně nestálá operace zápisu nezaručuje, že hodnota zapsaná by byla okamžitě viditelná pro ostatní procesory.

Klíčové volatile slovo lze použít u polí těchto typů:

  • Odkazové typy.
  • Typy ukazatelů (v nebezpečném kontextu). Všimněte si, že i když samotný ukazatel může být nestálý, objekt, na který odkazuje, nemůže. Jinými slovy, nemůžete deklarovat "ukazatel na nestálou".
  • Jednoduché typy jako sbyte, , byte, short, ushortintcharuint, float, a .bool
  • Typ enum s jedním z následujících základních typů: byte, sbyte, shortushort, , int, nebo uint.
  • Parametry obecného typu známé jako odkazové typy.
  • IntPtr a UIntPtr.

Jiné typy, včetně double a long, nelze označit volatile , protože čtení a zápisy do polí těchto typů nelze zaručit atomické. Pokud chcete chránit přístup s více vlákny k těmto typům polí, použijte Interlocked členy třídy nebo chraňte přístup pomocí příkazu lock .

Klíčové volatile slovo lze použít pouze u polí nebo classstruct. Místní proměnné nelze deklarovat volatile.

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 k provádění zpracování paralelně s primárním vláknem. Další informace o multithreadingu naleznete v tématu Spravované vlákno.

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.
}

volatile Při přidání modifikátoru k deklaraci _shouldStop místa se vždy zobrazí stejné výsledky (podobně jako výňatek zobrazený v předchozím kódu). Bez toho, aby byl tento modifikátor člena _shouldStop , je však chování nepředvídatelné. Metoda DoWork může optimalizovat přístup členů, 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é běhy 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é