[ThreadStatic]
ThreadLocal<T>
jenerik kullanırken özellik kullanılarak tanımlanır . Neden farklı tasarım çözümleri seçildi? Bu durumda nitelikler yerine genel özellikleri kullanmanın avantajları ve dezavantajları nelerdir?
[ThreadStatic]
ThreadLocal<T>
jenerik kullanırken özellik kullanılarak tanımlanır . Neden farklı tasarım çözümleri seçildi? Bu durumda nitelikler yerine genel özellikleri kullanmanın avantajları ve dezavantajları nelerdir?
Yanıtlar:
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 Foo
baş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>
.
ThreadLocal<T>
NET 4 ve üstü mevcuttur ve nitelik ayrıca aşağıda 3.5 ve kullanılabilir. ThreadStatic
ThreadLocal<T>
uygular IDisposable
ve genellikle kuvvetler Uygulamak IDisposable
sizi imha ve bu nedenle uygulamak için arayanları zorlar ki, hem IDisposable
... hem de
ThreadLocal
veya 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 .
static
mi? Bkz msdn.microsoft.com/en-us/library/...
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();
}
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, value
ana iş parçacığı dahil her ileti dizisi için ayrı bir kopyasına sahibiz .
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.