ThreadPool.QueueUserWorkItem vs Task.Factory.StartNew


79

Was ist der Unterschied zwischen den unten

ThreadPool.QueueUserWorkItem

vs.

Task.Factory.StartNew

Wenn der obige Code für eine lange laufende Aufgabe 500 Mal aufgerufen wird, bedeutet dies, dass alle Thread-Pool-Threads belegt werden?

Oder ist TPL (2. Option) intelligent genug, um nur Threads zu belegen, die weniger oder gleich der Anzahl der Prozessoren sind?

Antworten:


93

Wenn Sie eine lang laufende Aufgabe mit TPL starten möchten, sollten Sie angeben TaskCreationOptions.LongRunning, was bedeutet, dass sie nicht im Thread-Pool geplant wird. (BEARBEITEN: Wie in den Kommentaren erwähnt, handelt es sich um eine planerspezifische Entscheidung, die keine feste Garantie darstellt. Ich hoffe jedoch, dass jeder vernünftige Produktionsplaner das Planen lang laufender Aufgaben in einem Thread-Pool vermeiden würde.)

Sie sollten auf keinen Fall selbst eine große Anzahl von Aufgaben mit langer Laufzeit im Thread-Pool planen. Ich glaube, dass heutzutage die Standardgröße des Thread-Pools ziemlich groß ist (weil er oft auf diese Weise missbraucht wird), aber grundsätzlich sollte er nicht so verwendet werden.

Der Zweck des Thread-Pools besteht darin, zu vermeiden, dass kurze Aufgaben beim Erstellen eines neuen Threads einen großen Erfolg haben, verglichen mit der Zeit, in der sie tatsächlich ausgeführt werden. Wenn die Aufgabe längere Zeit ausgeführt wird, ist die Auswirkung des Erstellens eines neuen Threads ohnehin relativ gering - und Sie möchten möglicherweise nicht, dass Ihnen möglicherweise die Thread-Pool-Threads ausgehen. (Es ist jetzt weniger wahrscheinlich, aber ich habe es in früheren Versionen von .NET erlebt.)

Wenn ich die Option hätte, würde ich TPL definitiv verwenden, da die TaskAPI ziemlich gut ist - aber denken Sie daran, TPL mitzuteilen, dass Sie erwarten, dass die Aufgabe für eine lange Zeit ausgeführt wird.

BEARBEITEN: Wie in den Kommentaren erwähnt, siehe auch den Blog-Beitrag des PFX-Teams zur Auswahl zwischen TPL und Thread-Pool :

Abschließend möchte ich noch einmal wiederholen, was der ThreadPool-Entwickler des CLR-Teams bereits gesagt hat:

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

BEARBEITEN: Vergessen Sie auch aus Kommentaren nicht, dass Sie mit TPL benutzerdefinierte Scheduler verwenden können , wenn Sie wirklich ...


4
Ich bin vorsichtig mit der harten Regel, TaskCreationOptions.LongRunningdie immer den Thread-Pool vermeidet. Es scheint eher eine Richtlinie als eine Umsetzungsgarantie zu sein. Bin ich nicht auf der Basis?
Marc

1
@Marc: Nun, es liegt am Scheduler - aber es wäre ein ziemlich verrückter Scheduler, explizit lang laufende Aufgaben im Thread-Pool IMO zu planen.
Jon Skeet

Nur um ein bisschen mehr Infos hinzuzufügen - blogs.msdn.com/b/pfxteam/archive/2009/10/06/9903475.aspx
Brad Semrad

@Brad: Danke, werde einen Link zu meiner Antwort hinzufügen.
Jon Skeet

1
Ich möchte auch hinzufügen, dass Sie mit TPL Ihren eigenen Scheduler angeben können, einschließlich benutzerdefinierter Scheduler, mit denen Sie Ihre eigene Parallelität steuern können: msdn.microsoft.com/en-us/library/ee789351.aspx
Chris Shain
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.