Was passiert eigentlich bei der Verwendung von async/await innerhalb einer LINQ-Anweisung?
Dem folgenden snippet kompiliert, aber ich würde erwarten, dass es auf die Aufgabe führen, anstatt dass Sie mir einen List<Task<T>>
.
var foo = bars.Select(async bar => await Baz(bar)).ToList()
Als darauf hingewiesen,hier, müssen Sie Task.WhenAll
:
var tasks = foos.Select(async foo => await DoSomethingAsync(foo)).ToList();
await Task.WhenAll(tasks);
Aber ein Kommentar weist darauf hin, dass die async
und await
innerhalb der Select()
ist nicht erforderlich:
var tasks = foos.Select(foo => DoSomethingAsync(foo)).ToList();
Eine ähnliche Frage hier, wo jemand versucht, eine async-Methode in ein Where()
.
So async
und await
innerhalb einer LINQ-Anweisung Legale syntax, aber es funktioniert gar nichts zu tun oder hat es einen bestimmten verwenden?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Empfehle ich, dass Sie nicht denken, dass dies als "mit
async
innerhalb von LINQ". Halten Sie im Verstand, was zwischen den beiden: die Delegierten. Mehrere LINQ-Operatoren nehmen die Delegierten undasync
kann verwendet werden, um eine asynchrone Delegaten.So, wenn Sie eine asynchrone Methode
BazAsync
gibt eineTask
:dann dieser code führt eine Reihe von Aufgaben:
Ähnlich, wenn Sie
async
undawait
innerhalb der Delegierten, die Sie erstellen, eine asynchrone Delegaten zurückgibtTask
:Diese zwei LINQ-Ausdrücke, die funktionell äquivalent sind. Es gibt keine wichtigen Unterschiede.
Genauso wie normale LINQ-Ausdrücke, die
IEnumerable<Task>
faul ist-ausgewertet. Nur, mit asynchronen Methoden wieBazAsync
Sie in der Regel tun nicht wollen zufälligen double-Bewertung oder ähnliches. Also, wenn Sie Projekt, um eine Sequenz von Aufgaben, ist es normalerweise eine gute Idee, um sofort zu verdinglichen die Folge. Dies erfordertBazAsync
für alle Elemente in der Quell-Sequenz, starten alle Aufgaben gehen:Natürlich, alles, was wir getan haben, mit
Select
ist start eine asynchrone operation für jedes element. Wenn Sie möchten, zu warten, bis Sie alle abgeschlossen sind, dann verwenden SieTask.WhenAll
:Meisten anderen LINQ-Operatoren funktionieren nicht sauber mit asynchronen Delegaten.
Select
ist ziemlich einfach: Sie starten gerade eine asynchrone operation für jedes element.Sicher. Mit async und await innerhalb einer LINQ-Anweisung können Sie z.B. etwas wie das hier tun:
Ohne async/await innerhalb einer LINQ-Anweisung sind Sie nicht erwarten, etwas in die LINQ-Anweisung, so können Sie nicht verarbeiten, das Ergebnis, oder erwarten Sie etwas anderes.
Ohne async/await, in der LINQ-Anweisung, sind Sie nur starten von Aufgaben, aber nicht warten, bis Sie abgeschlossen ist. Sie werden noch vervollständigt, aber es wird passieren, lange nach der Kontrolle verlassen die LINQ-Anweisung, so können Sie nur auf Ihre Ergebnisse nach der
WhenAll
Linie wird abgeschlossen, aber nicht innerhalb der LINQ-Anweisung.