Aracılığıyla paylaş


volatile (C# Referansı)

volatile Bir alanın aynı anda yürütülen birden çok iş parçacığı tarafından değiştirilebileceğini belirtmek için anahtar sözcüğünü kullanın. Performans nedenleriyle, derleyici, çalışma zamanı sistemi ve hatta donanım, okumaları ve yazmaları bellek konumlarına yeniden düzenleyebilir. Alanı olarak volatile bildirmek, alanı belirli iyileştirme türlerinden dışlar. Tüm yürütme iş parçacıklarından görüldüğü gibi geçici yazmaların tek bir toplam sıralama garantisi yoktur. Daha fazla bilgi için sınıfına Volatile bakın.

Dikkat

Anahtar volatile kelimesi genellikle çoklu iş parçacığı programlamada yanlış anlaşılır ve yanlış kullanılır. Çoğu senaryoda yerine daha güvenli ve daha güvenilir alternatifler volatilekullanın. Modern .NET, Interlocked sınıfı, lock deyimi veya daha yüksek seviyeli eşitleme primitifleri gibi daha iyi eşzamanlılık araçları sağlar. Bu alternatifler, 'den volatiledaha net semantik ve daha güçlü garantiler sağlar. Yalnızca sınırlamalarını tam olarak anladığınız ve uygun çözüm olduğunu doğruladığınız nadir, gelişmiş senaryolarda kullanmayı volatile göz önünde bulundurun.

Uyarı

Çok işlemcili bir sistemde geçici okuma işlemi, herhangi bir işlemci tarafından bu bellek konumuna yazılan en son değeri almayı garanti etmez. Benzer şekilde, geçici bir yazma işlemi, yazılan değerin diğer işlemciler tarafından hemen görünür olmasını garanti etmez.

C# dili başvuru belgesi, C# dilinin en son yayımlanan sürümünü gösterir. Ayrıca, yaklaşan dil sürümü için genel önizlemelerdeki özelliklere yönelik ilk belgeleri içerir.

Belgelerde ilk olarak dilin son üç sürümünde veya geçerli genel önizlemelerde sunulan tüm özellikler tanımlanır.

Tavsiye

Bir özelliğin C# dilinde ilk tanıtıldığı zamanları bulmak için C# dil sürümü geçmişi makalesine bakın.

Anahtar sözcüğünü volatile şu türlerdeki alanlara uygulayın:

  • Referans türleri.
  • İşaretçi türleri (güvenli olmayan bir bağlamda). İşaretçinin kendisi geçici olsa da, işaret eden nesne olamaz. Başka bir deyişle, "geçici işaretçi" bildiremezsiniz.
  • sbyte, byte, short, ushort, int, uint, char, float ve bool gibi basit türler.
  • enum Aşağıdaki temel türlerden birine sahip bir tür: byte, sbyte, short, ushort, int, veya uint.
  • Referans türleri olarak bilinen genel tip parametreleri.
  • IntPtr ve UIntPtr.

ve longvolatile gibi double diğer türleri işaretleyemezsiniz çünkü bu türlerdeki alanlara yapılan okuma ve yazma işlemleri atomik olarak garantilenemez. Bu tür alanlara çok iş parçacıklı erişimi korumak için sınıf üyelerini Interlocked kullanın veya deyimini lock kullanarak erişimi koruyun.

Desteklenen türlerde bile çoğu çok iş parçacıklı senaryo için Interlocked işlemleri, lock deyimleri veya diğer senkronizasyon ilkelarını volatile yerine tercih edin. Bu alternatifler, hafif eşzamanlılık hatalarına daha az yatkındır.

Anahtar sözcüğünü volatile yalnızca veya classstructalanlarına uygulayabilirsiniz. Yerel değişkenleri olarak volatilebildiremezsiniz.

volatile için alternatifler

Çoğu durumda yerine şu daha güvenli alternatiflerden volatilebirini kullanın:

  • Interlocked işlemler: Sayısal türler ve referans atamaları için atomik işlemler sunar. Bu işlemler genellikle daha hızlıdır ve değerinden daha volatilegüçlü garantiler sağlar.
  • lock deyimi: Karşılıklı dışlama ve bellek engelleri sağlar. Daha büyük kritik bölümleri korumak için kullanın.
  • Volatile sınıfı: Anahtar sözcükten volatile daha net semantik ile belirgin volatile okuma ve yazma işlemleri sağlar.
  • Üst düzey eşitleme öncelikleri: ReaderWriterLockSlim, Semaphore veya System.Collections.Concurrent'den eşzamanlı koleksiyonlar gibi.

anahtar volatile sözcüğü atama dışındaki işlemler için bölünmezlik sağlamaz. Yarış koşullarını engellemez ve diğer bellek işlemleri için sipariş garantileri sağlamaz. Bu sınırlamalar, çoğu eşzamanlılık senaryosu için uygun değildir.

Aşağıdaki örnekte bir ortak alan değişkeninin olarak volatilenasıl bildirdiği gösterilmektedir.

class VolatileTest
{
    public volatile int sharedStorage;

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

Aşağıdaki örnek, bir yardımcı veya çalışan iş parçacığının birincil iş parçacığınınkiyle paralel olarak işleme gerçekleştirmek için nasıl oluşturulabileceğini ve kullanılabileceğini gösterir. Çoklu iş parçacığı kullanımı hakkında daha fazla bilgi için bkz. Yönetilen İş Parçacığı Oluşturma.

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

değiştiricisini volatile bildirimine _shouldStopeklediğinizde her zaman aynı sonuçları alırsınız (önceki kodda gösterilen alıntıya benzer). Ancak, _shouldStop değiştiricisi üyede olmadan davranış tahmin edilemez. DoWork yöntemi üye erişimini iyileştirerek eski verilerin okunmasıyla sonuçlanabilir. Çok iş parçacıklı programlamanın doğası gereği eski okuma sayısı tahmin edilemez. Programın farklı çalıştırmaları biraz farklı sonuçlar üretir.

C# dil belirtimi

Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# söz dizimi ve kullanımı için kesin kaynaktır.

Ayrıca bakınız