Je nach Code kann der einfachste Ansatz Parallel.For (Each) sein und die maximale Parallelität in den parallelen Optionen angeben.
Hinweis: Ich verlasse das hier auf Legacy. Tun Sie es nicht so, weil zu viele Aufgaben gleichzeitig auf WhenAny
warten. Und der Stapel wird tief werden.
Basierend auf diesem Code von Stephen Toub:
%Vor%Ich schrieb dies:
%Vor%Um zu verwenden, ersetzen Sie einfach:
%Vor%mit:
%Vor% Beachten Sie, dass wir den Aufruf der Aufgabe in einer Funktion f
umbrechen müssen, da wir sonst die Aufgabe bereits starten würden. Der zweite ThrottleAsync-Parameter ist ein beliebiges Objekt, das die "Gruppe" identifiziert. Ich habe eine Schnur benutzt. Alle asynchronen Aufgaben in der gleichen "Gruppe" sind auf CONCURRENT_TASKS
Aufgaben beschränkt, in diesem Fall 4.
Hier ist ein Beispielcode, der zeigt, wie nur vier Threads gleichzeitig ausgeführt werden. All Ready!
wird sofort angezeigt, da das Unterprogramm asynchron ist. Auch wenn die Threads in der Reihenfolge beginnen oder enden, befinden sich die Zeilen "output" immer noch in der gleichen Reihenfolge wie die Eingabe.
Ich mag diese Technik besser. Ich verwende TaskCompletionSource
, um Ausgabetasks für die eingehenden Aufgaben zu erstellen. Dies ist notwendig, weil ich ein Task
zurückgeben möchte, bevor ich es überhaupt ausführen kann! Die folgende Klasse verknüpft jede Eingabe Func(of Task(of Object))
mit einer TaskCompletionSource
, die sofort zurückgegeben wird und sie in eine Warteschlange stellt.
Elemente aus der Warteschlange werden in eine Liste laufender Aufgaben zurückgestellt und eine Fortsetzung setzt TaskCompletionSource
. Ein Aufruf von WhenAny
in einer Schleife sorgt dafür, dass Elemente aus der Warteschlange in die laufende Liste verschoben werden, wenn der Raum frei wird. Es gibt auch eine Überprüfung, um sicherzustellen, dass es nicht mehr als ein WhenAny
gleichzeitig gibt, obwohl es möglicherweise Probleme mit dem gemeinsamen Zugriff gibt.
Um synchrone Funktionen zu verwenden, ersetzen Sie einfach diese:
%Vor%mit diesem:
%Vor%Für Funktionen, die bereits eine Aufgabe zurückgeben, ist es wichtig, diese in Funktionen umzuwandeln, die Aufgabe zurückgeben, so dass der Hausmeister sie ausführen kann. Ersetzen:
%Vor%mit:
%Vor%Die folgende Klasse implementiert auch viele verschiedene Signaturen für Throttler.Run () abhängig davon, ob die Funktion sync / async ist, / nicht eingegeben hat, / nicht ausgegeben wurde. Konvertieren von Aufgabe zu Aufgabe (Of Output) ist besonders schwierig!
%Vor%Tags und Links .net async-await throttling