タスク並列ライブラリや継続と合わせて、システムリソースを効率的に使用することに興味があります。
GetResponseAsync()
別の最近の質問で定義された拡張メソッドを使用する次のシナリオを検討してください。
WebRequest request = HttpWebRequest.Create(uri);
Task<WebResponse> responseTask = request.GetResponseAsync(cancellationToken);
Func<Task<WebResponse>, WebResponse> continuation =
task =>
{
WebRequest followup = HttpWebRequest.Create(uri2);
return followup.GetResponseAsync(cancellationToken).Result;
};
Task<WebResponse> finalResultTask = responseTask.ContinueWith(continuation, cancellationToken);
この構成には複数の問題があり、これをどのように処理するのが最善かを考えています。これまでに確認した主な項目は次のとおりです。
のコアの実行は
responseTask
、非同期実行中にユーザー スレッドをブロックしないことで、リソースを効率的に使用します。ただし、継続はFunc
ラムダとして定義されているため、継続を実行するスレッドreturn
は、フォローアップ リクエストの実行が完了するまで、その行でブロックされます。より良い状況は、ユーザー スレッドをブロックせずに、継続のような動作を提供することです。キャンセルに関して
responseTask
との動作は異なります。実行finalResultTask
中に操作をキャンセルすると 状態になります。ただし、 の実行中に操作がキャンセルされた場合、プロパティにアクセスしようとすると例外が発生し、タスクが状態になります。responseTask
responseTask
TaskStatus.Canceled
finalResultTask
Result
TaskStatus.Failed
- 動作は、障害に関しても異なる場合があります。継続から戻るときにプロパティに
AggregateException
アクセスしようとしたときに がスローされた場合、二重にラップされた真の内部例外が発生する可能性があります (ここで特別なケースが発生するかどうかはわかりません)。最初のタスクで失敗した場合の実際の例外。Result
finalResultTask
InnerException
responseTask.Exception
- 動作は、障害に関しても異なる場合があります。継続から戻るときにプロパティに