3

我将如何编写一个由 1 +n 个异步调用 ( await) 组成的异步控制器操作?例如,假设我需要先检索对象Foo并且它具有可变数量的Bars标识符,并且我需要获取所有这些实体(为了这个问题,没有fetchBarsByFooId。我会使用Task.WaitAll还是可能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());
}
4

1 回答 1

5

嗯,首先要解决的是你是否真的想要并行,或者只是异步。只是异步很简单:

var bars = new List<Bar>();
foreach (var id in foo.Bars)
{
    bars.Add(await BarProvider.GetBarAsync(id));
}
return View(bars);

对于并行性,您可以使用Task.WhenAll

var tasks = foo.Bars.Select(id => BarProvider.GetBarAsync(id));
var bars = await Task.WhenAll(tasks);
return View(bars);

(我意识到这是比非并行版本更短的代码 - 但它在概念上更棘手。)

You should not use Parallel.For or Task.WaitAll as both of those are blocking calls - whereas Task.WhenAll returns you a task which will complete when all the subtasks have completed.

于 2012-11-21T14:58:18.110 回答