6

次のコードでは、task1とtask2は互いに独立しており、並行して実行できます。次の2つの実装の違いは何ですか?

var task1 = GetList1Async();
var task2 = GetList2Async();

await Task.WhenAll(task1, task2);

var result1 = await task1; 
var result2 = await task2; 

そして

var task1 = GetList1Async();
var task2 = GetList2Async();

var result1 = await task1; 
var result2 = await task2; 

なぜ私はどちらを選ぶべきなのでしょうか?

編集:私はGetList1Async()とGetList2Async()メソッドの戻り値の型が異なることを追加したいと思います。


  • 前者の場合、I4vvar result = await task1;まったく同じになりますvar result = task1.Result。私はそう思います.Resultもっと読みやすいです。 - dcastro
  • @ I4Vいや。どちらのスニペットでも、タスクは順次ではなく並列に実行されます。 - Servy
  • @ dcastro、彼らは同じではありません。例外の場合、.Resultを使用すると、異なる例外が生成されます。AggregateException使用時よりawait(最初の例外)async/awaitあなたが使うのを好むべきですawaitオーバー.Result例外動作の一貫性を保つため - Matt Smith
  • ただし、例外が発生した場合は、すべて待機中に例外がスローされ、その下の2行に到達することはありません。その下の2行に到達したと仮定すると、タスクがすでに完了していることが保証されているため、例外やデッドロックについて心配することなく.Resultを実行できます。参照するstackoverflow.com/a/24657079/1676558。 - user1676558

2 답변


10

最初の例では、両方のタスクが完了するのを待ってから両方の結果を取得します。

2番目の例では、タスクが一度に完了するのを待ちます。

あなたのコードには、どちらか明確なものを使用してください。両方のタスクの結果タイプが同じ場合は、次の場所から結果を取得できます。WhenAllなど:

var results = await Task.WhenAll(task1, task2);


  • 意図を明確にすることとは別に、条件が正しい場合(2つ以上のCPUコアがアイドル状態)、ソリューション1がソリューション2よりも並列である可能性はありますか? - Snakebyte
  • @Snakebyteいいえ、ありません。どちらも同じように機能しますが、最初の場合は非常にわずかな追加のオーバーヘッドしかありません。WhenAllむやみに - Servy
  • @Servy:どういう意味ですか?私が理解しているように、ステファンはexample1ではtask1とtask2が並列で実行されると述べています。例2では、それらは並列実行されず、タスク1が実行され、結果が完了するとメインスレッドは戻り、タスク2の実行を開始します。 - Maarten Kieft
  • @BlackHawkDesign:いいえ、どちらの場合もそうです実行する同時に。問題は、親メソッドかどうかです。待つ同時に、または一度に1人ずつ。 - Stephen Cleary
  • @ステフェンクリアリー:私はあなたが何を意味するかを見て、あなた/ serveryは正しいです。 2番目のコードは、次のように解釈しました。var task1 = await GetList1Async(); var task2 = await GetList2Async();その場合、それらは互いの後に実行されます。しかし、あなたは正しいです、この場合それらは両方とも平行に実行されます。 - Maarten Kieft

1

最初の構文は読みやすくなっています。 結果を得る前に、すべてのタスクが完了するのを待つつもりであることを明確に述べます。私はその代わりにそれを使用するのに十分合理的だと思います。

3番目または4番目のタスクを追加した場合も、書き込みが少なくなります。 すなわち:

await Task.WhenAll(task1, task2, task3, task4);

に比べ:

var result1 = await task1; 
var result2 = await task2; 
var result3 = await task3; 
var result4 = await task4; 


  • しかし最初のサンプルでは、彼は行って、とにかくすべてのコンポーネントタスクを待ちます。それを避けての戻り値を使用した場合、それは唯一の勝利です。WhenAll代わりに。 - Servy
  • 何が勝つ'この場合は主観的です。 Task.WhenAllは(Servyが知っているように)個々にタスクを待つのと完全に同じではありません。を見てみましょうstackoverflow.com/q/18310996/1676558あなたがこの問題についてもっと学び始めたいならば。 - user1676558

リンクされた質問


関連する質問

最近の質問