[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 Foo
diinisialisasi 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 ThreadStatic
atribut juga tersedia dalam 3.5 dan bawah.
ThreadLocal<T>
menerapkan IDisposable
dan biasanya memaksa Anda untuk menerapkan IDisposable
juga, yang memaksa penelepon Anda untuk membuang Anda dan karena itu menerapkannya IDisposable
juga ...
ThreadLocal
atau ThreadStatic
dengan 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 value
untuk 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.