Ich verwende die TPL, um neue Aufgaben zum System-Thread-Pool hinzuzufügen, indem ich die Funktion Task.Factory.StartNew()
verwende. Das einzige Problem ist, dass ich eine Menge Threads hinzufüge und ich denke, dass es zu viele für meinen Prozessor schafft. Gibt es eine Möglichkeit, eine maximale Anzahl von Threads in diesem Thread-Pool festzulegen?
Der Standardwert TaskScheduler
(erhalten von TaskScheduler.Default
) ist vom Typ (interne Klasse) ThreadPoolTaskScheduler
. Diese Implementierung verwendet die Klasse ThreadPool
, um Aufgaben in eine Warteschlange zu stellen (wenn Task
nicht mit TaskCreationOptions.LongRunning
erstellt wird - in diesem Fall wird für jede Aufgabe ein neuer Thread erstellt).
Wenn Sie also die Anzahl der Threads begrenzen möchten, die für Task
-Objekte verfügbar sind, die mit new Task(() => Console.WriteLine("In task"))
erstellt wurden, können Sie die verfügbaren Threads im globalen Threadpool wie folgt begrenzen:
Der Aufruf von ThreadPool.GetMaxThreads()
wird ausgeführt, um das Verkleinern von completionPortThreads
zu vermeiden.
Beachten Sie, dass dies eine schlechte Idee sein kann - da alle Tasks ohne einen bestimmten Scheduler und eine beliebige Anzahl anderer Klassen den Standard-ThreadPool verwenden, kann die zu niedrige Größe zu Nebenwirkungen führen: Starvation, etc.
Normalerweise bestimmt TPL eine gute "Standard" -Threadpoolgröße. Wenn Sie weniger Threads benötigen, lesen Sie Vorgehensweise: Erstellen eines Taskplaners, der den Grad der Parallelität begrenzt
Sie sollten zuerst Ihre Leistungsprobleme untersuchen. Es gibt verschiedene Probleme, die zu einer reduzierten Nutzung führen können:
In jedem Fall haben Sie ein Problem mit der Skalierbarkeit, das nicht einfach dadurch behoben werden kann, dass die Anzahl gleichzeitiger Aufgaben reduziert wird. Ihr Programm wird möglicherweise in Zukunft auf einem Zwei-, Vier- oder Acht-Kern-Rechner ausgeführt. Wenn Sie die Anzahl der geplanten Tasks begrenzen, führt dies zu einer Verschwendung von CPU-Ressourcen.
Normalerweise sollte der TPL-Scheduler eine gute Arbeit machen, wenn er auswählt, wie viele Aufgaben gleichzeitig ausgeführt werden sollen, aber wenn Sie wirklich die Kontrolle darüber haben wollen Mein Blogpost zeigt, wie dies sowohl mit Aufgaben als auch mit Aktionen funktioniert, und bietet ein Beispielprojekt, das Sie herunterladen und ausführen können, um beides zu sehen in Aktion.
Ein Beispiel dafür, wann Sie explizit einschränken möchten, wie viele Aufgaben gleichzeitig ausgeführt werden, ist, wenn Sie Ihre eigenen Dienste aufrufen und den Server nicht überlasten möchten.
Für das, was Sie beschreiben, klingt es, als könnten Sie mehr davon profitieren, dass Sie async / awa mit Ihren Aufgaben verwenden, um unnötigen Threadverbrauch zu vermeiden. Dies hängt jedoch davon ab, ob Sie CPU-gebundene Arbeit oder IO-gebundene Arbeit in Ihren Aufgaben ausführen. Wenn es IO-gebunden ist, können Sie davon profitieren, async / await zu verwenden.
Unabhängig davon haben Sie gefragt, wie Sie die Anzahl der Aufgaben begrenzen können, die gleichzeitig ausgeführt werden. Hier finden Sie einen Code, der zeigt, wie Sie dies mit Aktionen und Aufgaben tun können.
Wenn Sie Aktionen verwenden, können Sie die integrierte Funktion .Net Parallel.Invoke verwenden. Hier beschränken wir uns darauf, höchstens 3 Threads parallel zu betreiben.
%Vor%Da Sie hier jedoch Tasks verwenden, gibt es keine integrierte Funktion. Sie können jedoch das verwenden, das ich in meinem Blog zur Verfügung stelle.
%Vor%Und dann erstellen Sie Ihre Liste von Aufgaben und rufen Sie die Funktion, um sie laufen zu lassen, mit maximal 3 gleichzeitige gleichzeitig, können Sie dies tun:
%Vor%Tags und Links multithreading task-parallel-library c#-4.0