Bagaimana cara [ThreadStatic]
kerja atribut? Saya berasumsi bahwa kompilator akan memancarkan beberapa IL untuk mengisi / mengambil nilai di TLS, tetapi melihat pembongkaran tampaknya tidak melakukannya pada tingkat itu.
Sebagai tindak lanjut, apa yang terjadi jika Anda meletakkannya pada anggota non-statis? Kami meminta pengembang membuat kesalahan itu dan kompilator bahkan tidak memberikan peringatan.
Memperbarui
Pertanyaan kedua dijawab di sini: ThreadStatic Dimodifikasi dengan Static C #
c#
static
threadstatic
joshperry
sumber
sumber
public class SomeClass { public static MyContext myContext; ...
Sekarang segera setelah mengambil untaian kumpulan, lakukanSomeClass.myContext = new MyContext();
Jawaban:
Semantik implementasi dari thread statis berada di bawah level IL, dalam compiler jit .NET. Kompiler yang memancarkan IL seperti VB.NET dan C # tidak perlu tahu apa-apa tentang Win32 TLS untuk mengeluarkan kode IL yang dapat membaca dan menulis variabel yang memiliki atribut ThreadStatic. Tidak ada yang istimewa tentang variabel sejauh yang diketahui C # - itu hanya lokasi untuk membaca dan menulis sesuatu. Fakta bahwa ia memiliki atribut di atasnya bukanlah konsekuensi dari C #. C # hanya perlu mengetahui untuk memancarkan IL membaca atau menulis instruksi untuk nama simbol itu.
'Pengangkatan berat' dilakukan oleh CLR inti yang bertanggung jawab untuk membuat IL bekerja pada arsitektur perangkat keras tertentu.
Itu juga akan menjelaskan mengapa menempatkan atribut pada simbol yang tidak sesuai (non-statis) tidak mendapatkan reaksi dari kompilator. Kompilator tidak mengetahui semantik khusus apa yang dibutuhkan atribut. Alat analisis kode seperti FX / Cop, bagaimanapun, harus mengetahuinya.
Cara lain untuk melihatnya: CIL mendefinisikan satu set cakupan penyimpanan: penyimpanan statis (global), penyimpanan anggota, dan penyimpanan tumpukan. TLS tidak ada dalam daftar itu, sangat mungkin karena TLS tidak perlu ada dalam daftar itu. Jika instruksi baca dan tulis IL cukup untuk mengakses TLS ketika simbol ditandai dengan atribut TLS, mengapa IL harus memiliki representasi atau perlakuan khusus untuk TLS? Itu tidak dibutuhkan.
sumber
[ContextStatic]
atribut menutupi kasus itu juga (dengan namanya menyiratkan itu berfungsi berdasarkan konteks utas), tetapi saya mungkin salah dalam asumsi saya. Saya melihat orang-orang online mengatakan[ContextStatic]
atribut digunakan dengan Remoting.Anda dapat berpikir bahwa bidang yang ditandai dengan ThreadStatic dilampirkan ke utas dan masa pakainya sebanding dengan masa pakai utas.
Jadi dalam pseudocode
ThreadStatic
mirip (dengan semantik) memiliki nilai kunci yang dilampirkan ke utas:Thread.Current["MyClass.myVariable"] = 1; Thread.Current["MyClass.myvariable"] += 1;
tetapi sintaksnya sedikit lebih mudah:
class MyClass { [ThreadStatic] static int myVariable; } // .. then MyClass.myVariable = 1; MyClass.myVariable += 1;
Saya yakin ini diabaikan:
class A { [ThreadStatic] public int a; } [Test] public void Try() { var a1 = new A(); var a2 = new A(); a1.a = 5; a2.a = 10; a1.a.Should().Be.EqualTo(5); a2.a.Should().Be.EqualTo(10); }
Selain itu, perlu disebutkan bahwa
ThreadStatic
tidak memerlukan mekanisme sinkronisasi apa pun dibandingkan dengan bidang statis normal (karena status tidak dibagikan).sumber
"MyClass.myVariable"
, bukan?TransactionScope
mereka menyimpan segala macam hal di sana untuk cakupan ( referensiource.microsoft.com/#System.Transactions/System/… )[ThreadStatic] membuat versi terisolasi dari variabel yang sama di setiap utas.
Contoh:
[ThreadStatic] public static int i; // Declaration of the variable i with ThreadStatic Attribute. public static void Main() { new Thread(() => { for (int x = 0; x < 10; x++) { i++; Console.WriteLine("Thread A: {0}", i); // Uses one instance of the i variable. } }).Start(); new Thread(() => { for (int x = 0; x < 10; x++) { i++; Console.WriteLine("Thread B: {0}", i); // Uses another instance of the i variable. } }).Start(); }
sumber
Bidang yang ditandai dengan
[ThreadStatic]
dibuat di Thread Local Storage sehingga setiap utas memiliki salinannya sendiri dari bidang tersebut, yaitu ruang lingkup bidang bersifat lokal ke utas.Kolom TLS adalah akses melalui register segmen gs / fs. Segmen ini digunakan oleh kernel OS untuk mengakses memori khusus thread. Kompilator .net tidak memancarkan IL apa pun untuk memasukkan / mengambil nilai di TLS. Itu dilakukan oleh kernel OS.
sumber