volatile (C# 參考)

volatile 關鍵字指出某個欄位可能是由同時執行的多個執行緒所修改。 編譯器、執行階段系統,甚至硬體都有可能基於效能因素,而重新排列對記憶體位置的讀取和寫入。 宣告從特定類型最佳化中排除 volatile 的欄位。 不保證 volatile 寫入的單一總排序如所有執行緒的執行中所示。 如需詳細資訊,請參閱 Volatile 類別。

注意

在多處理器系統上,揮發性讀取作業不保證取得任何處理器寫入該記憶體位置的最新值。 同樣地,揮發性寫入作業不保證其他處理器會立即看到寫入的值。

volatile 關鍵字可以套用至下列類型的欄位:

  • 參考型別。
  • 指標類型 (在不安全的內容中)。 請注意,雖然指標本身可為 volatile,但它所指向的物件不得為 volatile。 換句話說,您無法將指標宣告為 volatile。
  • 簡單型別,例如 sbytebyteshortushortintuintcharfloatbool
  • 使用下列其中一個基底類型的 enum 型別:bytesbyteshortushortintuint
  • 已知為參考型別的泛型型別參數。
  • IntPtrUIntPtr

其他型別,包括 doublelong,不能標示為 volatile,因為對這些型別之欄位的讀取和寫入不保證是不可部分完成。 若要保護對這些型別之欄位的多執行緒存取,請使用 Interlocked 類別成員,或使用 lock 陳述式來保護存取。

volatile 關鍵字只能套用至 classstruct 的欄位。 區域變數不可以宣告為 volatile

範例

下列範例示範如何將公用欄位變數宣告為 volatile

class VolatileTest
{
    public volatile int sharedStorage;

    public void Test(int i)
    {
        sharedStorage = i;
    }
}

下列範例示範如何建立和使用輔助或背景工作執行緒,以運用主執行緒的輔助或背景工作執行緒來執行平行處理。 如需有關多執行緒的詳細資訊,請參閱 Managed 執行緒處理

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 修飾詞新增到 _shouldStop 的宣告之後,您將會一律取得相同的結果 (類似上述程式碼顯示的摘要)。 不過,如果 _shouldStop 成員上沒有修飾詞,則行為是無法預測的。 DoWork 方法可能會將成員存取最佳化,導致讀取過時的資料。 由於多執行緒程式設計的特性,過時讀取的數目是無法預測的。 程式不同次的執行會產生不同的結果。

C# 語言規格

如需詳細資訊,請參閱<C# 語言規格>。 語言規格是 C# 語法及用法的限定來源。

另請參閱