ThreadPool.QueueUserWorkItem vs Task.Factory.StartNew - PullRequest
73 голосов
/ 09 февраля 2012

в чем разница между ниже

ThreadPool.QueueUserWorkItem

против

Task.Factory.StartNew

Если приведенный выше код вызывается 500 раз для какой-то длительной задачи, значит ли это, что все потоки пула потоков будут заняты?

Или TPL (второй вариант) будет достаточно умен, чтобы просто принимать потоки меньше или равным числу процессоров?

1 Ответ

89 голосов
/ 09 февраля 2012

Если вы собираетесь запустить долгосрочное задание с TPL, вы должны указать TaskCreationOptions.LongRunning, что будет означать, что не планирует это в потоке- бассейн. (РЕДАКТИРОВАТЬ: Как отмечалось в комментариях, это является решением, специфичным для планировщика, и не является твердой и быстрой гарантией, но я надеюсь, что любой разумный производственный планировщик избежит планирования долгосрочных задач на пул потоков.)

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

Смысл пула потоков состоит в том, чтобы избегать коротких задач, получающих большой удар от создания нового потока, по сравнению со временем, когда они фактически выполняются. Если задача будет выполняться в течение длительного времени, влияние создания нового потока в любом случае будет относительно небольшим - и вы не захотите в конечном итоге исчерпать потоки пула потоков. (Сейчас это менее вероятно, но я испытал в более ранних версиях .NET.)

Лично, если бы у меня была возможность, я бы определенно использовал TPL на том основании, что API Task довольно хорош - но do не забудьте сообщить TPL, что вы ожидаете, что задача будет выполняться для долгое время.

РЕДАКТИРОВАТЬ: Как отмечено в комментариях, см. Также сообщение в блоге команды PFX на выбор между TPL и пулом потоков :

В заключение я повторю то, что разработчик ThreadPool команды CLR уже заявил:

Task is now the preferred way to queue work to the thread pool.

РЕДАКТИРОВАТЬ: Также из комментариев, не забывайте, что TPL позволяет вам использовать пользовательских планировщиков , если вы действительно хотите ...

...