2013-04-07 10 views
6

私は3つのタスクを並行して実行する必要があります。私は3つすべてを待ってから、結果を処理し続ける必要があります。したがって、次のようになります。タスクのバッチで部分的な成功を処理するにはどうすればよいですか?

3つのタスクがすべて正常に完了すると、正常に動作します。しかし、それらのいずれかが失敗した場合、私はすべての方法をバブルアップする例外が発生します。これは私が望むものではありません。これらのタスクのいずれかがInvalidOperationExceptionを処理しても処理を続行できる場合は、スローされた例外にアクセスするにはprocessメソッドが必要です。

私はタスク内でtry...catchができることを認識していますが、それはハックのようには見えません。意味的に間違っている(タスクDIDが失敗する - それは正常に返るべきではない)、私がこのアプローチを行った場合、結果が成功するか、例外を返すので、カスタムタイプを返さなければならない。しかしながら、Task<T>オブジェクトは既にExceptionチャンネルを公開しているので、私は二重課税をしないで、すでに存在しているものを使うだけです。あなたは以下の私の例のように、このケースを扱うことができる

+0

私が正しく理解していれば、あなたは 'var combinedTask = Task.WhenAll(...); combinedTask.IgnoreExceptions();を待ちます。戻りプロセス(combinedTask); '? 'IgnoreExceptions()'は例外をスローせずにフォールト 'Task'を'待つ 'ことができる場所です。あるいは、結果には正確に何が含まれるべきですか? – svick

+0

@svick - 私は同意します、結果はおそらく一貫したタイプではないようです。私の考えは、ここではTaskオブジェクトで直接作業し、async/awaitファサードは使用しないでください。エラーに関係なくすべてのタスクが完了するようにすれば、それらのタスクオブジェクトで作業することができますが、その方法はわかりません。 –

+0

@svick - 存在するものは 'IgnoreExceptions()'ですか?私はそれを見つけることができません。 –

答えて

2

:私が正しくあなたを理解していれば

Task<T>[] tasks = new Task<T>[] { task1, task2, task3 }; 

try 
{ 
    await Task.WhenAll(tasks); 
} 
catch(InvalidOperationException exception) // If you need to handle any other exception do it 
{ 
    // handle it if you wan to 
} 

// You can use task1.IsFauled to know if current task failed, 
// and you can use task1.Exception to know why it failed 

return process(tasks.Where(t => !t.IsFauled).ToArray()); 
+0

したがって、task1の実行に1秒かかる場合、task2は2、task3は3、task1はエラーをスローします。この状況では、task2とtask3はまだ完了していますか?彼らはキャンセルされるようです。 –

+0

また、このような状況でどのタスクが例外をスローしたのかを知るにはどうすればよいですか? –

+0

@GeorgeMauerどうすれば取り消すことができますか? 'Task'はそのようにキャンセルされません。CancellationTokenSource'と' WhenAll() 'はそれにアクセスできません。 – svick

1

、あなたはこのを探していますか?

var tasks = new[] { task1, task2, task3 }; 
try { await Task.WhenAll(tasks); } catch (...) { } 
return process(tasks); 
関連する問題