当通过ThreadPool循环时,我的ThreadStatic变量中的值是否仍然存在?

时间:2009-05-12 21:33:55

标签: .net multithreading threadpool thread-static

我正在使用ThreadStatic变量来存储一些数据,但我担心在完成它并释放回ThreadPool后,我存储在线程上的数据仍然存在。在完成线程之前,我是否需要担心清除ThreadStatic变量?或者ThreadPool会在为下一个QueueUserWorkItem“传递出去”之前为我做这个吗?这对我来说尤其重要,因为我需要确保我的应用程序中的其他线程有一个干净的平板来处理ThreadStatic变量。谢谢!

2 个答案:

答案 0 :(得分:12)

线程池(按设计)使线程在调用之间保持活动状态。这意味着ThreadStatic变量将在对QueueUserWorkItem。

的调用之间保持不变

这种行为也是你不应该依赖的。 ThreadPool将(最终自行决定)释放线程并让它们结束,并根据需要构造新线程。

但是,如果您遇到问题,我会质疑您的设计。如果您需要在QueueUserWorkItem中使用特定的确定性ThreadStatic数据,那么您的线程例程可能是自己进行线程处理的良好候选者。 ThreadStatic和ThreadPool并不总是很好的组合 - 你不一定有足够的控制(因为ThreadPool管理线程)真正利用ThreadStatic变量并从中受益。你永远不会知道两个工作项是否会在同一个线程,不同的线程,以及是否应该(重新)初始化线程静态变量等。

答案 1 :(得分:5)

我希望它们会保留在方法之间。当然,如果有疑问,请在worker方法的开头重置线程静态变量。或者使用try / finally清除每个工作单元后的值。

(编辑)

很容易证明他们确实存在;上面的内容很快就会开始打印高于0的数字(如果不同的工人被隔离,那么每次都是0):

[STAThread]
static void Main()
{
    for (int i = 0; i < 50; i++)
    {
        ThreadPool.QueueUserWorkItem(DoStuff);
    }
    Console.ReadLine();
}
static void DoStuff(object state)
{
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId + ": " + value++);
    Thread.Sleep(20);
}
[ThreadStatic]
static int value;