ThreadStatic vs ThreadLocal <T>: genel nitelikten daha mı iyi?


Yanıtlar:


114

Yorumlarda belirtilen blog gönderisinin açık bir şekilde ifade etmediği, ancak çok önemli bulduğum bir [ThreadStatic]şey, her konu için otomatik olarak bir şeyler başlatılmamasıdır. Örneğin, şuna sahip olduğunuzu söyleyin:

[ThreadStatic]
private static int Foo = 42;

Bunu kullanan ilk iş parçacığı, olarak Foobaşlatıldığını görecektir 42. Ancak sonraki konular olmayacak. Başlatıcı yalnızca ilk iş parçacığı için çalışır. Böylece, başlatılıp başlatılmadığını kontrol etmek için kod yazmak zorunda kalırsınız.

ThreadLocal<T> Bu sorunu, öğeye ilk erişilmeden önce çalışan bir başlatma işlevi (Reed'in blogunun gösterdiği gibi) sağlamanıza izin vererek çözer.

Bence [ThreadStatic]bunun yerine kullanmanın bir avantajı yok ThreadLocal<T>.


20
Belki hariç ThreadLocal<T>NET 4 ve üstü mevcuttur ve nitelik ayrıca aşağıda 3.5 ve kullanılabilir. ThreadStatic
Jeroen

2
Ve değeri ayarlamak için başlatıcıları kullanmıyorsanız, bunun yerine onu başlatmadan sonra daha sonraki bir noktada ayarlıyorsanız, [ThreadStatic] kullanımı sözdizimsel olarak daha temizdir.
Düşünce

9
Ve dışında ThreadLocal<T>uygular IDisposableve genellikle kuvvetler Uygulamak IDisposablesizi imha ve bu nedenle uygulamak için arayanları zorlar ki, hem IDisposable... hem de
Stefan STEINEGGER

4
@StefanSteinegger: Havuz konuları kullanırken ThreadLocalveya kullanırken çok dikkatli olurdum ThreadStatic. Bu değerler, yalnızca atadığınız görev için değil, havuz iş parçacığının tüm ömrü boyunca kalacaktır. Bu, bazı bariz olmayan şekillerde sorun yaşamanıza neden olabilir. Daha fazla bilgi için stackoverflow.com/questions/561518/… ve benzer sorulara bakın .
Jim Mischel

3
Örnekteki alanın da beyan edilmesi gerekmez staticmi? Bkz msdn.microsoft.com/en-us/library/...
entheh

39

ThreadStatic Yalnızca ilk iş parçacığında başlat, her iş parçacığı için ThreadLocal Initialize. Aşağıda basit gösteri:

    public static ThreadLocal<int> _threadlocal =
        new ThreadLocal<int>(() =>
        {
            return Thread.CurrentThread.ManagedThreadId;
        });

    public static void Main()
    {
        new Thread(() =>
        {
            for (int x = 0; x < _threadlocal.Value; x++)
            {
                Console.WriteLine("First Thread: {0}", x);
            }
        }).Start();

        new Thread(() =>
        {
            for (int x = 0; x < _threadlocal.Value; x++)
            {
                Console.WriteLine("Second Thread: {0}", x);
            }
        }).Start();

        Console.ReadKey();
    }

görüntü açıklamasını buraya girin


16

ThreadStatic'in arkasındaki ana fikir , her iş parçacığı için değişkenin ayrı bir kopyasını tutmaktır .

class Program
    {
        [ThreadStatic]
        static int value = 10;

        static void Main(string[] args)
        {
            value = 25;

            Task t1 = Task.Run(() =>
            {
                value++;
                Console.WriteLine("T1: " + value);
            });
            Task t2 = Task.Run(() =>
            {
                value++;
                Console.WriteLine("T2: " + value);
            });
            Task t3 = Task.Run(() =>
            {
                value++;
                Console.WriteLine("T3: " + value);
            });

            Console.WriteLine("Main Thread : " + value);

            Task.WaitAll(t1, t2, t3);
            Console.ReadKey();
        }
    }

Yukarıdaki ön bilgide, valueana iş parçacığı dahil her ileti dizisi için ayrı bir kopyasına sahibiz .

görüntü açıklamasını buraya girin

Bu nedenle, bir ThreadStatic değişkeni, oluşturulduğu evre dışındaki diğer evrelerde varsayılan değerine başlatılacaktır.

Her iş parçacığındaki değişkeni kendi yöntemimizle başlatmak istiyorsak, ThreadLocal'ı kullanın.


1
Ve tam makale burada bulunabilir .
Daniel Dušek
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.