Ist es möglich, Async bei Verwendung von ForEach zu verwenden? Unten ist der Code, den ich versuche:
using (DataContext db = new DataLayer.DataContext())
{
db.Groups.ToList().ForEach(i => async {
await GetAdminsFromGroup(i.Gid);
});
}
Ich erhalte den Fehler:
Der Name 'Async' existiert im aktuellen Kontext nicht
Die Methode, in der die using-Anweisung enthalten ist, ist auf asynchron gesetzt.
c#
async-await
James Jeffery
quelle
quelle
List.ForEach()
nicht Teil von LINQ ist.async
. Sie waren sehr hilfreich!foreach
mit einemawait
in deinem Loop-Körper.ForEach
nur einen synchronen Delegatentyp und es gibt keine Überlastung für einen asynchronen Delegattyp . Die kurze Antwort lautet also "niemand hat eine asynchrone geschriebenForEach
". Die längere Antwort ist, dass Sie eine gewisse Semantik annehmen müssten; z. B. sollten die Artikel einzeln (wieforeach
) oder gleichzeitig (wieSelect
) verarbeitet werden? Wären asynchrone Streams nicht eine bessere Lösung? Wenn gleichzeitig, sollten die Ergebnisse in der ursprünglichen Artikelreihenfolge oder in der Reihenfolge der Fertigstellung vorliegen? Sollte es beim ersten Fehler fehlschlagen oder warten, bis alle abgeschlossen sind? Usw.SemaphoreSlim
diese Option, um asynchrone Aufgaben zu drosseln.Diese kleine Erweiterungsmethode sollte Ihnen eine ausnahmesichere asynchrone Iteration bieten:
Da wir den Rückgabetyp des Lambda von
void
auf ändernTask
, werden Ausnahmen korrekt weitergegeben. Auf diese Weise können Sie in der Praxis so etwas schreiben:quelle
async
sollte vorher seini =>
ForEachAsync
ist im Wesentlichen eine Bibliotheksmethode, daher sollte das Warten wahrscheinlich mit konfiguriert werdenConfigureAwait(false)
.Die einfache Antwort besteht darin, das
foreach
Schlüsselwort anstelle derForEach()
Methode von zu verwendenList()
.quelle
Hier ist eine aktuelle Arbeitsversion der oben genannten asynchronen foreach-Varianten mit sequentieller Verarbeitung:
Hier ist die Implementierung:
Was ist der Hauptunterschied?
.ConfigureAwait(false);
Dadurch bleibt der Kontext des Hauptthreads erhalten, während die sequentielle Verarbeitung jeder Aufgabe asynchronisiert wird.quelle
Zunächst
C# 8.0
können Sie Streams asynchron erstellen und verwenden.Mehr
quelle
MoveNext
den Enumerator warten . Dies ist wichtig in Fällen, in denen der Enumerator das nächste Element nicht sofort abrufen kann und warten muss, bis eines verfügbar ist.Fügen Sie diese Erweiterungsmethode hinzu
Und dann benutze so:
quelle
Das Problem war, dass das
async
Schlüsselwort vor dem Lambda und nicht vor dem Body stehen muss:quelle
async void
. Dieser Ansatz hat Probleme mit der Ausnahmebehandlung und dem Wissen, wann die asynchronen Vorgänge abgeschlossen sind.