ThreadPool.QueueUserWorkItem проти Task.Factory.StartNew


79

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

ThreadPool.QueueUserWorkItem

проти

Task.Factory.StartNew

Якщо вищезазначений код викликається 500 разів для якогось тривалого завдання, чи означає це, що всі потоки пулу потоків будуть зайняті?

Або TPL (2-й варіант) буде достатньо розумним, щоб просто зайняти потоки, менші або рівні кількості процесорів?

Відповіді:


93

Якщо ви збираєтеся розпочати довготривале завдання з TPL, вам слід вказати TaskCreationOptions.LongRunning, що означатиме, що воно не планує його в пулі потоків. (EDIT: Як зазначено в коментарях, це рішення, яке відповідає планувальнику, і не є жорсткою та швидкою гарантією, але я сподіваюсь, що будь-який розумний планувальник виробництва уникне планування довготривалих завдань у пулі потоків.)

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

Суть пулу потоків полягає у тому, щоб уникнути коротких завдань, які б не потрапили під значний удар від створення нового потоку, порівняно з часом, який вони насправді виконують. Якщо завдання буде виконуватися протягом тривалого часу, вплив створення нового потоку в будь-якому випадку буде відносно невеликим - і ви не хочете, щоб в кінцевому підсумку закінчилися потоки пулу потоків. (Це менш імовірно, але я зробив випробувати його на більш ранніх версіях .NET.)

Особисто, якби у мене була можливість, я б точно використовував TPL на тій підставі, що TaskAPI дуже приємний - але не забудьте сказати TPL, що ви очікуєте, що завдання буде виконуватися протягом тривалого часу.

РЕДАГУВАТИ: Як зазначається в коментарях, див. Також публікацію блогу команди PFX про вибір між TPL та пулом потоків :

На закінчення я ще раз повторю те, що розробник команди CLR ThreadPool вже заявив:

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

EDIT: Також із коментарів не забувайте, що TPL дозволяє використовувати власні планувальники , якщо ви дійсно хочете ...


4
Я з обережністю ставлюся до жорсткого правила, яке TaskCreationOptions.LongRunningзавжди уникатиме пулу потоків. Здається, це більше директива, ніж гарантія реалізації. Я не на базі цього?
Марк

1
@Marc: Ну, це залежить від планувальника, але було б досить божевільним планувальником планувати явно тривалі завдання в пулі потоків, IMO.
Джон Скіт,

Просто щоб додати трохи більше інформації - blogs.msdn.com/b/pfxteam/archive/2009/10/06/9903475.aspx
Бред Семрад

@Brad: Дякую, додаю посилання на мою відповідь.
Джон Скіт,

1
Я також додам, що TPL дозволяє вказати власний планувальник, включаючи спеціальні планувальники, які дозволяють контролювати власну паралельність: msdn.microsoft.com/en-us/library/ee789351.aspx
Кріс Шейн,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.