キャンセルトークンを受け付ける複数のタスクがあり、それに応じてThrowIfCancellationRequested
を呼び出します。これらのタスクは、Task.WhenAll
を使用して同時に実行されます。タスクが例外をスローすると、すべてのタスクがキャンセルされるようにします。正しくTask.WhenAllをキャンセルし、最初の例外をスローするには?
var cts = new CancellationTokenSource();
try
{
var tasks = new Task[] { DoSomethingAsync(cts.Token), ... } // multiple tasks here
.Select(task => task.ContinueWith(task =>
{
if (task.IsFaulted)
{
cts.Cancel();
}
}));
await Task.WhenAll(tasks).ConfigureAwait(false);
}
catch (SpecificException)
{
// Why is this block never reached?
}
私は、これは、これを行うための最善の方法であるかどうかわからないんだけど、いくつかの問題を持っているようだ:私はこれはSelect
とContinueWith
を使用して達成しました。例外は内部的にキャッチされ、WhenAll
のコードに常に到達したようです。私は、例外が発生したときにWhenAll
の後のコードに到達したくないのですが、コールスタックの別のレベルで手動でキャッチできるように例外がスローされてしまいます。これを達成する最良の方法は何ですか?可能であれば、コールスタックをそのまま残したいと思います。複数の例外が発生した場合は、最初の例外のみが再スローされた場合は、AggregateException
でない方が最適です。関連ノートで
、私はそうのようContinueWith
にキャンセルトークンを渡してみました:task.ContinueWith(lambda, cts.Token)
。しかし、任意のタスクの例外が発生した場合、これは私が興味を持っている例外の代わりにTaskCanceledException
を投げます。私が望むもの
これはTask.WhenAll '程度であるということです'タスクの外側でtry-catchを使用します。もう一つの質問は、複数の 'ContinueWith'に参加し、task.Exceptionを明示的にチェックすることです。 –
違いは関係ありません。 'WhenAll'は' ContinueWIth'を使用して独自の継続を追加するだけで、それが自分自身に障害があるかどうかを判断する際に 'Exception'値をチェックしています。 'WhenAll'の場面の後ろで起こっていることのいくつかは、問題を説明したり修正したりすることと意味が異なるわけではありません。 – Servy
@Servy私はあなたの説明や他のスレッドが、通常どおりに例外をスローさせて、コールスタックの別のレベルでTPL以外の例外を処理できるようにする方法について私の質問にどう答えているのか分かりません。 –