class MyClass {
[ThreadStatic]
static int myVariable;
}
// .. then
MyClass.myVariable = 1;
MyClass.myVariable += 1;
如果你把它放在一个非静态成员上会发生什么?
我认为它被忽视了:
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);
}
线程静态的实现语义低于 IL 级别,在。NET jit 编译器。向 IL 发出的编译器,如 VB.NET 和 C # ,不需要知道任何关于 Win32 TLS 的信息,就可以发出可以读写具有 ThreadStatic 属性的变量的 IL 代码。就 C # 所知,这个变量并没有什么特别之处——它只是一个读写东西的位置。事实上,它上面有一个属性对 C # 来说是无关紧要的。C # 只需要知道发出该符号名的 IL 读或写指令。
[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();
}
The field marked with [ThreadStatic] are created on Thread Local Storage so every thread has it own copy of the field i.e the scope of the fields are local to the thread.
TLS 字段是通过 gs/fs 段寄存器访问的。操作系统内核使用这些段来访问特定于线程的内存。那个。Net 编译器不会发出任何 IL 来填充/检索 TLS 中的值。它是由操作系统内核完成的。