[ThreadStatic]
屬性如何工作?我認爲編譯器會發出一些IL來填充/檢索TLS中的值,但是看到反彙編似乎並沒有在這個層次上做到這一點。ThreadStatic屬性如何工作?
作爲一個後續,如果你把它放在非靜態成員上會發生什麼?我們有一個開發人員犯了這個錯誤,編譯器甚至沒有提出警告。
更新
第二個問題回答這裏:ThreadStatic Modified with Static C#
[ThreadStatic]
屬性如何工作?我認爲編譯器會發出一些IL來填充/檢索TLS中的值,但是看到反彙編似乎並沒有在這個層次上做到這一點。ThreadStatic屬性如何工作?
作爲一個後續,如果你把它放在非靜態成員上會發生什麼?我們有一個開發人員犯了這個錯誤,編譯器甚至沒有提出警告。
更新
第二個問題回答這裏:ThreadStatic Modified with Static C#
在.NET JIT編譯器中,線程靜態的實現語義低於IL級別。像VB.NET和C#一樣發佈到IL的編譯器不需要知道任何關於Win32 TLS的內容,就可以發出IL代碼來讀寫具有ThreadStatic屬性的變量。只要C#知道這個變量沒有什麼特別之處 - 它只是一個讀取和寫入內容的位置。它對它有一個屬性的事實對C#沒有任何影響。 C#只需要知道如何爲該符號名稱發送IL讀取或寫入指令。
'繁重'由核心CLR完成,負責使IL在特定的硬件架構上工作。
這也可以解釋爲什麼將屬性放在不合適的(非靜態)符號上不會得到編譯器的反應。編譯器不知道該屬性需要什麼特殊的語義。代碼分析工具如FX/Cop應該知道它。
另一種查看方式:CIL定義了一組存儲範圍:靜態(全局)存儲,成員存儲和堆棧存儲。 TLS不在該列表中,很可能是因爲TLS不需要在該列表中。如果IL讀寫指令足以在TLS屬性標記符號時訪問TLS,爲什麼IL對TLS有特殊的表示或處理?這不是必需的。
如何[ThreadStatic]屬性 工作?
您可以認爲標記爲ThreadStatic的字段已附加到線程,並且其生存期與線程的生命週期相當。
所以僞ThreadStatic
是(通過語義)與具有連接到一個線程鍵值:
Thread.Current["MyClass.myVariable"] = 1;
Thread.Current["MyClass.myvariable"] += 1;
但語法是隻是更容易一點:
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);
}
另外值得一提的是,相比於普通的靜態字段(因爲狀態不共享)ThreadStatic
不需要任何同步機制。
第二個像僞代碼應該是'「MyClass.myVariable」',不是嗎? – akshay2000 2016-09-18 11:50:25
我不確定確切的限制條件,但我只想指出,如果它不一定是原始類型並不明顯。如果您查看「TransactionScope」的源代碼,他們會爲該範圍存儲各種內容(https://referencesource.microsoft.com/#System.Transactions/System/Transactions/Transaction.cs,0e19ea1e3a994306) – 2017-03-27 02:15:21
如果生成的IL是相同的(確實是這樣),那麼運行時必須特別編碼,以知道如何分配和讀取值,當它擊中這樣一個裝飾字段。看起來像一個黑客:) – 2011-03-08 02:45:13