mehrere parallele asynchrone Aufrufe mit Warten
-
12-11-2019 - |
Frage
Soweit ich weiß, verpackt die Laufzeit, wenn sie auf die folgende Anweisung stößt, den Rest der Funktion als Rückruf für die Methode, die asynchron aufgerufen wird (someCall()
in diesem Beispiel).In diesem Fall anotherCall()
wird als Rückruf ausgeführt someCall()
:
await someCall();
await anotherCall();
Ich frage mich, ob es möglich ist, die Laufzeit wie folgt auszuführen:Anruf someCall()
auf asynchrone Weise und kehren Sie sofort zum aufrufenden Thread zurück und rufen Sie ihn dann auf anotherCall()
ähnlich (ohne zu warten someCall
fertigstellen).Weil ich benötige, dass diese beiden Methoden asynchron ausgeführt werden, und ich annehme, dass es sich bei diesen Aufrufen lediglich um Fire-and-Forget-Aufrufe handelt.
Ist es möglich, dieses Szenario mit just zu implementieren? async
Und await
(Old nicht verwenden begin
/end
Mechanismus)?
Lösung
Das async/await enthält einige Operatoren, die bei der parallelen Komposition helfen, wie z WhenAll
Und WhenAny
.
var taskA = someCall(); // Note: no await
var taskB = anotherCall(); // Note: no await
// Wait for both tasks to complete.
await Task.WhenAll(taskA, taskB);
// Retrieve the results.
var resultA = taskA.Result;
var resultB = taskB.Result;
Andere Tipps
Der einfachste Weg ist wahrscheinlich, dies zu tun:
var taskA = someCall();
var taskB = someOtherCall();
await taskA;
await taskB;
Das ist besonders schön, wenn Sie die Ergebniswerte haben möchten:
var result = await taskA + await taskB;
Sie müssen es also nicht tun taskA.Result
.
TaskEx.WhenAll
könnte schneller sein als zwei Wartevorgänge nacheinander.Ich weiß es nicht, da ich dazu keine Leistungsuntersuchung durchgeführt habe, aber es sei denn, Sie sehen ein Problem, denke ich, dass die beiden aufeinanderfolgenden Wartezeiten besser lesen, insbesondere wenn Sie die Ergebniswerte wünschen.
Das Async-CTP wird nicht mehr benötigt, sofern Sie .NET 4.5 verwenden.Beachten Sie, dass die asynchrone Funktionalität vom Compiler implementiert wird, sodass .NET 4-Apps sie verwenden können, zum Kompilieren ist jedoch VS2012 erforderlich.
TaskEx wird nicht mehr benötigt.Das CTP konnte das vorhandene Framework nicht ändern und verwendete daher Erweiterungen, um Dinge zu erreichen, die die Sprache in 5.0 bewältigen würde.Verwenden Sie einfach Task direkt.
Deshalb habe ich hiermit den Code neu geschrieben (beantwortet von Stephen Cleary), indem ich TaskEx durch Task ersetzt habe.
var taskA = someCall(); // Note: no await
var taskB = anotherCall(); // Note: no await
// Wait for both tasks to complete.
await Task.WhenAll(taskA, taskB);
// Retrieve the results.
var resultA = taskA.Result;
var resultB = taskB.Result;