[ThreadStatic]didefinisikan menggunakan atribut sementara ThreadLocal<T>menggunakan generik. Mengapa solusi desain yang berbeda dipilih? Apa keuntungan dan kerugian menggunakan atribut generik over dalam kasus ini?
[ThreadStatic]didefinisikan menggunakan atribut sementara ThreadLocal<T>menggunakan generik. Mengapa solusi desain yang berbeda dipilih? Apa keuntungan dan kerugian menggunakan atribut generik over dalam kasus ini?
Jawaban:
Sesuatu yang dicatat oleh posting blog di komentar tidak membuatnya eksplisit, tetapi menurut saya sangat penting, adalah itu [ThreadStatic]tidak secara otomatis menginisialisasi hal-hal untuk setiap utas. Misalnya, Anda memiliki ini:
[ThreadStatic]
private static int Foo = 42;
Utas pertama yang menggunakan ini akan melihat Foodiinisialisasi ke 42. Tetapi utas berikutnya tidak akan. Penginisialisasi hanya berfungsi untuk utas pertama. Jadi Anda akhirnya harus menulis kode untuk memeriksa apakah sudah diinisialisasi.
ThreadLocal<T> memecahkan masalah itu dengan membiarkan Anda menyediakan fungsi inisialisasi (seperti yang ditunjukkan blog Reed) yang dijalankan sebelum pertama kali item tersebut diakses.
Menurut pendapat saya, tidak ada keuntungan menggunakan [ThreadStatic]daripada ThreadLocal<T>.
ThreadLocal<T>tersedia di NET 4 dan atas, dan yang ThreadStaticatribut juga tersedia dalam 3.5 dan bawah.
ThreadLocal<T>menerapkan IDisposabledan biasanya memaksa Anda untuk menerapkan IDisposablejuga, yang memaksa penelepon Anda untuk membuang Anda dan karena itu menerapkannya IDisposablejuga ...
ThreadLocalatau ThreadStaticdengan utas kumpulan. Nilai-nilai tersebut akan tetap ada sepanjang masa pakai utas kumpulan, tidak hanya untuk tugas yang Anda tetapkan. Itu dapat menyebabkan masalah bagi Anda dalam beberapa cara yang tidak terlalu jelas. Lihat stackoverflow.com/questions/561518/… dan pertanyaan serupa untuk info lebih lanjut.
static? Lihat msdn.microsoft.com/en-us/library/…
ThreadStatic Inisialisasi hanya pada utas pertama, ThreadLocal Inisialisasi untuk setiap utas. Di bawah ini adalah demonstrasi sederhana:
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();
}

Ide utama di balik ThreadStatic adalah mempertahankan salinan variabel terpisah untuk setiap utas .
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();
}
}
Dalam cuplikan di atas, kami memiliki salinan terpisah valueuntuk setiap utas, termasuk utas utama.
Jadi, variabel ThreadStatic akan diinisialisasi ke nilai defaultnya di utas lain kecuali utas tempat ia dibuat.
Jika kita ingin menginisialisasi variabel pada setiap utas dengan cara kita sendiri, gunakan ThreadLocal.