2017-10-16 15 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