How would I go about writing an async controller action that is made up of 1 +n async calls (await)? E.g. let’s pretend I need to retrieve the object Foo first and it has a variable number of Bars identifier and I need to fetch all those entities (for the sake of this question, there is no fetchBarsByFooId. Would I use Task.WaitAll or maybe Parallel.For?
public async Task<ActionResult> Bars(int id) {
Foo foo = await this.FooProvider.GetFooAsync(id);
var bars = new ConcurrentQueue<Bar>();
// Sub-optimal version
foreach (int barId in foo.BarIDs) {
Bar bar = this.BarProvider.GetBar(barId);
bars.Enqueue(bar)
}
// Fetch each bar asynchronously and pass them to the view.
....
return View(bars.ToArray());
}
Well, the first thing to work out is whether you actually want parallelism, or just asynchrony. Just asynchrony is simple:
For parallelism, you could use
Task.WhenAll:(I realize this is shorter code than the non-parallel version – but it’s more conceptually tricky.)
You should not use
Parallel.FororTask.WaitAllas both of those are blocking calls – whereasTask.WhenAllreturns you a task which will complete when all the subtasks have completed.