如何为线程池中的每个新线程初始化标记有ThreadStaticAttribute的静态字段?

时间:2017-10-16 07:59:01

标签: c# multithreading async-await

我有一个标有ThreadStaticAttribute的字段。它在主线程中初始化,但我的代码使用了很多async/await构造和Parallel库,这就是我不知道将执行多少线程的原因。我想确保每个线程都初始化了这个字段。我该怎么做?

1 个答案:

答案 0 :(得分:4)

使用ThreadStaticAttribute,您无法以您想要的方式执行初始化。实际上,文档说明您根本不应该执行任何初始化:

  

不要为标有的字段指定初始值   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与线程池线程(就像您一样)可能会导致令人惊讶的行为,因为当线程返回到池时,不会清除本地线程存储。所以你可能会“开始”一个新的线程(当线程被从池中删除时),并且该线程可能已经在前一次迭代中留下的ThreadStatic`ThreadLocal`字段中具有值。