2017-10-16 14 views
3

我有一個標有ThreadStaticAttribute的字段。它在主線程中被初始化,但是我的代碼使用了很多async/await結構和Parallel庫,這就是爲什麼我不知道要執行多少個線程的原因。我想確保每個線程都將此字段初始化。我該怎麼做?如何初始化線程池中每個新線程標記爲ThreadStaticAttribute的靜態字段?

+0

您可以在首次訪問時初始化它(即 - 您想讀取值,請參閱字段尚未初始化 - 初始化它)。 – Evk

+0

@Evk在訪問之前有什麼方法可以初始化它嗎? –

+2

我不這麼認爲。實際上初始化它是不鼓勵的,因爲docs聲明:「不要爲用ThreadStaticAttribute標記的字段指定初始值,因爲這種初始化只發生一次,當類構造函數執行時,因此隻影響一個線程。」我想,你可以使用'ThreadLocal '來做你想做的事。 – Evk

回答

4

隨着ThreadStaticAttribute你不能以你想要的方式執行初始化。 Actully,文檔指出你不應該執行在所有的初始化:

的字段標有 ThreadStaticAttribute不要指定初始值,因爲這樣的初始化類的構造函數執行時只發生一次, ,因此隻影響一個 線程

但是,您可以使用替代:ThreadLocal<T>

private ThreadLocal<string> _myVar = new ThreadLocal<string>(() => "some string"); 

var s = _myVar.Value; // separate for each thread 
_myVar.Value = "changed"; 

請注意,ThreadLocal<T>執行IDisposable,因此必須在您完成後處置。

您也可以實現ThreadStatic字段的單獨訪問器,該字段將首先檢查字段是否已初始化,如果未初始化,則初始化該字段,然後返回值(類似於單例模式)。由於ThreadStatic字段,因此不需要任何鎖就可以線程安全。

另請注意,使用ThreadStaticThreadLocal與線程池線程(就像您一樣)可能會導致令人驚訝的行爲,因爲當線程返回到池時本地線程存儲不會被清除。所以你可能會「開始」一個新的線程(當真正的線程退出池中時),並且該線程可能已經在上一次迭代中留下的`ThreadLocal`字段中具有值ThreadStatic