C # async warten mit LINQ ForEach ()

8

Ich habe den folgenden Code, der korrekt async / await-Paradigma verwendet.

%Vor%

Wie schreibe ich das, wenn ich statt foreach () LINQ ForEach () benutzen möchte? Dieser gibt zum Beispiel Kompilierungsfehler.

%Vor%

Der einzige Code, den ich ohne Kompilierungsfehler arbeiten konnte, ist dies.

%Vor%

Ich mache mir Sorgen, dass diese Methode keine asynchrone Signatur hat, sondern nur der Körper. Ist das das korrekte Äquivalent zu meinem ersten Block?

    
SamDevx 15.05.2015, 13:33
quelle

5 Antworten

11

Nein. Es ist nicht. Diese ForEach unterstützt nicht async-await und erfordert, dass Ihr Lambda async void ist, was für Event-Handler only verwendet werden sollte. Wenn Sie es verwenden, werden alle Ihre async -Operationen gleichzeitig ausgeführt und warten nicht darauf, dass sie abgeschlossen werden.

Sie können wie gewohnt eine normale foreach verwenden, aber wenn Sie eine Erweiterungsmethode wünschen, benötigen Sie eine spezielle async Version.

Sie können selbst eine erstellen, die über die Elemente iteriert, eine Operation async und await s it:

ausführt %Vor%

Verwendung:

%Vor%

Eine andere (und normalerweise effizientere) Implementierung von ForEachAsync wäre, alle async -Operationen und nur dann await alle zusammen zu starten, aber das ist nur möglich, wenn Ihre Aktionen gleichzeitig ausgeführt werden können, was nicht der Fall ist immer der Fall (zB Entity Framework):

%Vor%

Wie in den Kommentaren angemerkt wurde, möchten Sie wahrscheinlich nicht SaveChangesAsync in einer foreach verwenden, um damit zu beginnen. Es ist wahrscheinlich effizienter, Ihre Änderungen vorzubereiten und sie dann auf einmal zu speichern.

    
i3arnon 15.05.2015 13:46
quelle
0

Um in eine Methode zu schreiben, muss Ihre Methode als async markiert werden. Wenn Sie ForEach-Methode schreiben, die Sie schreiben, erwarten Sie in Ihrem Labda-Ausdruck, der in Begriffen verschiedene Methoden insgesamt ist, die Sie von Ihrer Methode aufrufen. Sie müssen diesen lamdba-Ausdruck in eine Methode verschieben und diese Methode als async markieren und auch als @ i3arnon sagen Sie benötigen eine Async-markierte ForEach-Methode, die noch nicht von .Net Framework bereitgestellt wird. Also müssen Sie es selbst schreiben.

    
Pramod Jangam 15.05.2015 13:52
quelle
0

Das erste Beispiel mit foreach wartet nach jeder Schleifeniteration effektiv. Das letzte Beispiel ruft List<T>.ForEach() auf, das eine Action<T> Bedeutung hat, dh Ihr asynchrones Lambda wird in ein void Delegat kompiliert, im Gegensatz zu standard Task .

Effektiv ruft die ForEach() -Methode "Iterationen" einzeln auf, ohne darauf zu warten, dass sie beendet werden. Dies wird auch an Ihre Methode weitergegeben, was bedeutet, dass AddReferenceData() möglicherweise beendet wird, bevor die Arbeit erledigt ist.

Also nein, es ist kein Äquivalent und verhält sich ganz anders . Wenn man davon ausgeht, dass es sich um einen EF-Kontext handelt, wird es explodieren, da es möglicherweise nicht für mehrere Threads gleichzeitig verwendet wird.

Lesen Sie auch Ссылка , das von Deepu erwähnt wird warum ist es wahrscheinlich besser, bei foreach zu bleiben.

    
Jacek Gorgoń 15.05.2015 13:46
quelle
0

Warum nicht die Methode AddRange () verwenden?

%Vor%     
Tzu 20.08.2015 22:17
quelle
0

Vielen Dank für Ihr Feedback. Wenn ich den "save" -Teil außerhalb der Schleife nehme, glaube ich, dass die folgenden zwei Methoden nun äquivalent sind: eine mit foreach() , eine andere mit .ForEach() . Wie von Deepu erwähnt, werde ich Eric's Beitrag lesen, warum foreach vielleicht besser ist.

%Vor%     
SamDevx 15.05.2015 14:26
quelle

Tags und Links