I am using ThreadStatic variables to store some data, but I am worried that the data I store on the thread will still be there after I am finished with it and release back to the ThreadPool. Do I need to worry about clearing my ThreadStatic variables before I am finished with the thread? Or will the ThreadPool do this for me before "passing it out" for the next QueueUserWorkItem? This is especially important for me because I need to make sure that other threads in my app have a clean slate to work from in terms of ThreadStatic variables. Thanks!
问题:
回答1:
The thread pool (by design) keeps the threads alive between calls. This means that the ThreadStatic variables will persist between calls to QueueUserWorkItem.
This behavior is also something you should not count on. The ThreadPool will (eventually, at its discretion) release threads back and let them end, and construct new threads as needed.
However, I'd question your design if you're running into problems with this. If you need specific, deterministic ThreadStatic data to be used in QueueUserWorkItem, your threading routines might be good candidates for doing the thread handling yourself. ThreadStatic and the ThreadPool aren't always a great combination - you just don't necessarily have enough control (since the ThreadPool manages the threads) to really take advantage and get benefits from ThreadStatic variables. You'll never know whether two work items will be on the same thread, different threads, and whether the threadstatic variable should be (re)initialized, etc.
回答2:
I expect they would remain between methods. Of course, if in doubt, reset the thread-static variables at the start of your worker method. Or use try
/finally
to clear the values after each unit-of-work.
(edit)
It is pretty easy to prove that they do indeed remain; the above quickly starts printing numbers higher than 0 (where 0 each time is what we would expect if the different workers were isolated):
[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;