3

1 + n 個の非同期呼び出し ( ) で構成される非同期コントローラー アクションを作成するにはどうすればよいawaitですか? たとえば、最初にオブジェクトを取得する必要がありFoo、それには可変数のBars識別子があり、それらすべてのエンティティを取得する必要があるとしましょう (この質問のために、 はありfetchBarsByFooIdませTask.WaitAllParallel.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);

(これは非並列バージョンよりも短いコードであることに気付きましたが、概念的にはよりトリッキーです。)

これらの両方が呼び出しをブロックしているため、 orを使用しないでください- 一方、すべてのサブタスクが完了すると完了するタスクを返します。Parallel.ForTask.WaitAllTask.WhenAll

于 2012-11-21T14:58:18.110 に答える