Forward Warning
Nur eine schnelle Warnung an diejenigen, die diesen und andere ähnliche Threads besuchen und nach einem Weg suchen, EntityFramework mithilfe des async+await+task-Toolsets zu parallelisieren: Das hier gezeigte Muster ist solide, jedoch werden Sie bei dem speziellen EF-Sonderfall keine parallele Ausführung erreichen, es sei denn, Sie verwenden eine separate (neue) db-Kontext-Instanz innerhalb jedes einzelnen *Async()-Aufrufs.
Dies ist auf die inhärenten Designeinschränkungen von ef-db-Kontexten zurückzuführen, die das Ausführen mehrerer Abfragen parallel in der gleichen ef-db-Kontext-Instanz verbieten.
Basierend auf den bereits gegebenen Antworten ist dies der Weg, um sicherzustellen, dass Sie alle Werte sammeln, auch wenn eine oder mehrere der Aufgaben zu einer Ausnahme führen:
public async Task Foobar() {
async Task Awaited(Task a, Task b, Task c) {
return DoSomething(await a, await b, await c);
}
using (var carTask = BuyCarAsync())
using (var catTask = FeedCatAsync())
using (var houseTask = SellHouseAsync())
{
if (carTask.Status == TaskStatus.RanToCompletion //triple
&& catTask.Status == TaskStatus.RanToCompletion //cache
&& houseTask.Status == TaskStatus.RanToCompletion) { //hits
return Task.FromResult(DoSomething(catTask.Result, carTask.Result, houseTask.Result)); //fast-track
}
cat = await catTask;
car = await carTask;
house = await houseTask;
//oder Task.AwaitAll(carTask, catTask, houseTask);
//oder await Task.WhenAll(carTask, catTask, houseTask);
//je nachdem, wie Sie die Fehlerbehandlung bevorzugen
return Awaited(catTask, carTask, houseTask);
}
}
Eine alternative Implementierung, die mehr oder weniger die gleichen Leistungsmerkmale aufweist, könnte sein:
public async Task Foobar() {
using (var carTask = BuyCarAsync())
using (var catTask = FeedCatAsync())
using (var houseTask = SellHouseAsync())
{
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 DoSomething(cat, car, house);
}
}