Будут ли значения в моих переменных ThreadStatic сохраняться при циклическом переключении через ThreadPool? - PullRequest
13 голосов
/ 13 мая 2009

Я использую переменные ThreadStatic для хранения некоторых данных, но меня беспокоит, что данные, которые я храню в потоке, все еще будут там после того, как я закончу с этим и вернусь обратно в ThreadPool. Нужно ли беспокоиться об очистке моих переменных ThreadStatic до того, как я закончу с потоком? Или ThreadPool сделает это для меня перед тем, как «передать его» для следующего QueueUserWorkItem? Это особенно важно для меня, потому что мне нужно убедиться, что другие потоки в моем приложении имеют чистый лист для работы с точки зрения переменных ThreadStatic. Спасибо!

Ответы [ 2 ]

12 голосов
/ 13 мая 2009

Пул потоков (по замыслу) поддерживает работу потоков между вызовами. Это означает, что переменные ThreadStatic будут сохраняться между вызовами QueueUserWorkItem.

На это поведение тоже не стоит рассчитывать. ThreadPool будет (в конечном счете, по своему усмотрению) возвращать потоки обратно и позволять им заканчиваться, а также создавать новые потоки по мере необходимости.

Однако я бы поставил под сомнение ваш дизайн, если у вас возникнут проблемы с этим. Если вам нужны конкретные, детерминированные данные ThreadStatic для использования в QueueUserWorkItem, ваши подпрограммы потоков могут быть хорошими кандидатами для самостоятельной обработки потоков. ThreadStatic и ThreadPool не всегда являются отличной комбинацией - вам просто не обязательно иметь достаточный контроль (поскольку ThreadPool управляет потоками), чтобы действительно использовать преимущества и получать преимущества от переменных ThreadStatic. Вы никогда не узнаете, будут ли два рабочих элемента в одном и том же потоке, в разных потоках и должна ли (ре) инициализироваться переменная потока и т. Д.

5 голосов
/ 13 мая 2009

Я ожидаю, что они останутся между методами. Конечно, если вы сомневаетесь, сбросьте статические переменные потока в начале вашего рабочего метода. Или используйте 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;
...