タスクと同じ完了したタスクを待機します。結果? 質問する

タスクと同じ完了したタスクを待機します。結果? 質問する

私は現在「C# における並行処理のクックブックスティーブン・クリアリー著の「」を読んでいて、次のテクニックに気づきました。

var completedTask = await Task.WhenAny(downloadTask, timeoutTask);  
if (completedTask == timeoutTask)  
  return null;  
return await downloadTask;  

downloadTaskは の呼び出しでありhttpclient.GetStringAsynctimeoutTaskを実行していますTask.Delay

タイムアウトしなかった場合、 はすでに完了しています。タスクがすでに完了しているのに、downloadTaskを返すのではなく 2 番目の await を実行する必要があるのはなぜですか?downloadTask.Result

ベストアンサー1

すでにいくつかの良い回答やコメントがありますが、私も一言言わせていただきます...

私が(または)awaitよりも を好む理由は2つあります。1つ目は、エラー処理が異なることです。 は例外を でラップしません。理想的には、非同期コードは、特にResultWaitawaitAggregateExceptionAggregateException望むに。

2つ目の理由はもう少し微妙です。私のブログ(および本)で説明しているように、Result/Waitデッドロックを引き起こす可能性がある、 そしてasyncメソッド内で使用すると、さらに微妙なデッドロックを引き起こす可能性があるResult. コードを読んでいてまたは を見つけたらWait、それはすぐに警告フラグになります。Result/ はWait絶対に確実タスクがすでに完了していることを示します。これは一目で確認するのが難しいだけでなく (実際のコードでは)、コードの変更に対しても脆弱です。

ResultそれはそうでWaitあるべきだと言っているわけではない一度もない使用できます。私は自分のコードで以下のガイドラインに従っています。

  1. アプリケーション内の非同期コードでは のみを使用できますawait
  2. 非同期ユーティリティ コード (ライブラリ内) では、コードが本当に必要とする場合にResult/ を使用することがあります。このような使用法にはコメントを付ける必要があるでしょう。Wait
  3. 平行タスクコードではResultと を使用できますWait

(1) は圧倒的に一般的なケースであるため、私はawaitどこでもこれを使用し、他のケースを一般規則の例外として扱う傾向があることに注意してください。

おすすめ記事