私は現在、Stephen Clearyによる「Concurrency in C#Cookbook」を読んでいますが、次のようなテクニックに気付きました。
var completedTask = await Task.WhenAny(downloadTask, timeoutTask);
if (completedTask == timeoutTask)
return null;
return await downloadTask;
downloadTaskhttpclient.GetStringAsyncへの呼び出しです。timeoutTaskTask.Delayを実行しています。
タイムアウトしなかった場合、downloadTaskはすでに完了しています。タスクが既に完了しているため、なぜdownloadTask.Resultを返さずにもう一度待つ必要があるのでしょうか。
ここにはすでにいくつかの良い答え/コメントがありますが、ただ参加するには...
私が好む理由は2つあります。await
オーバーResult
(またはWait
) 1つは、エラー処理が異なることです。await
で例外をラップしません。AggregateException
。理想的には、非同期コードは決して対処する必要はないはずです。AggregateException
特に明記しない限り、望むに。
第二の理由はもう少し微妙です。私のブログで(そして本の中で)説明しているように、Result
/Wait
デッドロックを引き起こす可能性があります、そしてで使用すると、さらに微妙なデッドロックが発生する可能性があります。async
方法。だから、コードを読んでいると、Result
またはWait
、それは即時の警告フラグです。のResult
/Wait
あなたがいる場合だけ正しいです絶対確実タスクは既に完了していること。一見して(実世界のコードで)これを見るのが難しいだけでなく、それはまたコード変更に対してより脆弱です。
それは言うことではありませんResult
/Wait
すべき決して利用される。私は自分のコードでこれらのガイドラインに従います。
await
。Result
/Wait
コードが本当にそれを要求しているなら。そのような用法はおそらくコメントがあるはずです。Result
そしてWait
。(1)がはるかに一般的なケースであることに注意してください。await
他の場合は一般的な規則の例外として扱ってください。
await
を防ぐAggregateException
ラッパー。AggregateException
非同期プログラミングではなく、並列プログラミング用に設計されています。 - Stephen ClearyWait
に参加することでした動的タスク並列処理
Task
インスタンス。非同期を待つためにそれを使うTask
インスタンスは危険です。マイクロソフトは、新しい「約束」の導入を検討しました。タイプ、しかし既存のものを使用することを選びましたTask
代わりに既存のものを再利用することのトレードオフTask
非同期タスクのタイプは、非同期コードで使用してはいけないいくつかのAPIを使用することになります。 - Stephen Cleary
これは理にかなっているtimeoutTask
の製品ですTask.Delay
それが本の中にあると私は信じています。
Task.WhenAny
戻るTask<Task>
内部タスクは引数として渡したものの1つです。このように書き直すことができます。
Task<Task> anyTask = Task.WhenAny(downloadTask, timeoutTask);
await anyTask;
if (anyTask.Result == timeoutTask)
return null;
return downloadTask.Result;
どちらの場合も、downloadTask
すでに完成していますが、非常に小さな違いがあります。return await downloadTask
そしてreturn downloadTask.Result
。それは後者が投げるということですAggregateException
コメントで@KirillShlenskiyが指摘したように、これは元の例外をすべてラップします。前者は元の例外を再度スローするだけです。
どちらの場合も、例外を処理する場所はどこでも、確認する必要があります。AggregateException
とにかく、その内部の例外は、エラーの原因に到達するために。
downloadTask
そしてtimeoutTask
?彼らは何をしますか? - Mike PerrenoudAggregateException
とResult
対最初の例外ExceptionDispatchInfo
とawait
) Stephen Toubの「.NET 4.5でのタスク例外処理」で詳しく説明しています。blogs.msdn.com/b/pfxteam/archive/2011/09/28/…) - Kirill Shlenskiy