Будут ли значения в моих ThreadStatic переменных по-прежнему сохраняться при циклическом использовании ThreadPool?

StackOverflow https://stackoverflow.com/questions/854976

Вопрос

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

Это было полезно?

Решение

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

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

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

Другие советы

Я ожидаю, что они останутся между методами.Конечно, если вы сомневаетесь, сбросьте статические переменные потока в начале вашего рабочего метода.Или использовать 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;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top