1. ホーム
  2. c#

複数待ち vs Task.WaitAll - 同等?

2023-09-13 13:59:55

質問

パフォーマンスに関して、以下の2つのメソッドは実行可能でしょうか? GetAllWidgets()GetAllFoos() を並列に並べるのですか?

どちらかを使うべき理由はあるのでしょうか?コンパイラの裏側でいろいろなことが起こっているようなので、明確にはわかりません。

方法A:複数のawaitを使用する方法 ==================================================================================================

public async Task<IHttpActionResult> MethodA()
{
    var customer = new Customer();

    customer.Widgets = await _widgetService.GetAllWidgets();
    customer.Foos = await _fooService.GetAllFoos();

    return Ok(customer);
}

================================= MethodB: Task.WaitAllを利用する ==================================================================================

public async Task<IHttpActionResult> MethodB()
{
    var customer = new Customer();

    var getAllWidgetsTask = _widgetService.GetAllWidgets();
    var getAllFoosTask = _fooService.GetAllFos();

    Task.WaitAll(new List[] {getAllWidgetsTask, getAllFoosTask});

    customer.Widgets = getAllWidgetsTask.Result;
    customer.Foos = getAllFoosTask.Result;

    return Ok(customer);
}

=====================================

どのように解決するのですか?

最初のオプションは、2つの操作を同時に実行しません。1つ目の処理を実行し、その完了を待って、2つ目の処理を実行します。

2番目のオプションは、両方を同時に実行しますが、同期的に(つまり、スレッドをブロックしながら)待ちます。

1番目のオプションは2番目のオプションより遅く完了し、2番目のオプションは必要なくスレッドをブロックするので、両方のオプションを使用するべきではありません。

で非同期に両方の操作を待つべきです。 Task.WhenAll :

public async Task<IHttpActionResult> MethodB()
{
    var customer = new Customer();

    var getAllWidgetsTask = _widgetService.GetAllWidgets();
    var getAllFoosTask = _fooService.GetAllFos();

    await Task.WhenAll(getAllWidgetsTask, getAllFoosTask);

    customer.Widgets = await getAllWidgetsTask;
    customer.Foos = await getAllFoosTask;

    return Ok(customer);
}

ただし Task.WhenAll が完了した後、両方のタスクがすでに完了しているので、それらを待つとすぐに完了することに注意してください。