Wie kann ich asynchrone Funktionen in .Net drosseln?

8

Ich verwende async-await in .Net. Wie kann ich die Anzahl gleichzeitiger asynchroner Anrufe begrenzen?

    
Eyal 15.09.2012, 17:04
quelle

4 Antworten

6

Ein relativ einfacher Weg ist die Verwendung von TPL Dataflow. Etwas wie:

%Vor%     
svick 15.09.2012, 17:21
quelle
0

Je nach Code kann der einfachste Ansatz Parallel.For (Each) sein und die maximale Parallelität in den parallelen Optionen angeben.

    
James Manning 15.09.2012 18:52
quelle
0

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.

%Vor%     
Eyal 15.09.2012 17:04
quelle
0

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%     
Eyal 17.09.2012 22:49
quelle

Tags und Links