Warnung vorwärts
Nur eine kurze Kopfnuss für diejenigen, die diese und andere ähnliche Threads besuchen und nach einem Weg suchen, um EntityFramework mithilfe des async+await+task-Toolsets zu parallelisieren: Das hier gezeigte Muster ist solide, jedoch werden Sie bei dem speziellen Schneeflocken-Problem von EF keine parallele Ausführung erreichen, es sei denn, Sie verwenden eine separate (neue) db-Kontext-Instanz in jedem einzelnen *Async() Aufruf.
Dies ist auf die inhärenten Designbeschränkungen von ef-db-Kontexten zurückzuführen, die das gleichzeitige Ausführen mehrerer Abfragen in derselben ef-db-Kontextinstanz verbieten.
Basiert auf den bereits gegebenen Antworten, so sammeln Sie alle Werte, selbst wenn einer oder mehrere der Tasks zu einer Ausnahme führen:
public async Task Foobar() {
async Task Erwartet(Task a, Task b, Task c) {
return MachEtwas(await a, await b, await c);
}
using (var carTask = KaufAutoAsync())
using (var catTask = FüttereKatzeAsync())
using (var houseTask = HausVerkaufenAsync())
{
if (carTask.Status == TaskStatus.RanToCompletion //dreifach
&& catTask.Status == TaskStatus.RanToCompletion //cache
&& houseTask.Status == TaskStatus.RanToCompletion) { //treffer
return Task.FromResult(MachEtwas(catTask.Result, carTask.Result, houseTask.Result)); //schnellzugriff
}
cat = await catTask;
car = await carTask;
house = await houseTask;
//oder Task.AwaitAll(carTask, catTask, houseTask);
//oder await Task.WhenAll(carTask, catTask, houseTask);
//es hängt davon ab, wie Sie die Fehlerbehandlung lieber mögen
return Erwartet(catTask, carTask, houseTask);
}
}
Ein alternativer Ansatz, der mehr oder weniger die gleiche Leistungsfähigkeit hat, könnte sein:
public async Task Foobar() {
using (var carTask = KaufAutoAsync())
using (var catTask = FüttereKatzeAsync())
using (var houseTask = HausVerkaufenAsync())
{
cat = catTask.Status == TaskStatus.RanToCompletion ? catTask.Result : (await catTask);
car = carTask.Status == TaskStatus.RanToCompletion ? carTask.Result : (await carTask);
house = houseTask.Status == TaskStatus.RanToCompletion ? houseTask.Result : (await houseTask);
return MachEtwas(cat, car, house);
}
}