2012-09-03 11 views
7

は、私は私のコードに次の行があります。すべてのタスクが正常に完了したことを確認する方法は?

var taskA = Task.Factory.StartNew(WorkA); 
    var taskB = Task.Factory.StartNew(WorkB); 
    var allTasks = new[] { taskA, taskB }; 

    Task.Factory.ContinueWhenAll(allTasks, tasks => FinalWork(), TaskContinuationOptions.OnlyOnRanToCompletion); 

をしかし、私はこれを実行すると、私は次のエラーを取得する:オプションTaskContinuationOptions.OnlyOnRanToCompletionによって引き起こされる

It is invalid to exclude specific continuation kinds for continuations off of multiple tasks.

私の質問は、()FinalWorkをします(すべてのタスクのステータスがRanToCompletionある)と、すべてのタスクが正常に自分の仕事を行っていることを確認する方法ですか? その間、アプリケーションは他のタスクを実行します。

+0

何が 'Task'sの一部に障害が発生した場合何をしたいですか? – svick

+0

'Task'sのいくつかが失敗した場合、何もしないでください。 – Zen

答えて

11

@Peter Ritchieと@Ben McDougallの回答に基づいて解決策を見つけました。

private static void FinalWork(Task[] tasks) 
{ 
    if (tasks.All(t => t.Status == TaskStatus.RanToCompletion)) 
    { 
     // do "some work" 
    } 
} 

すべてtasksステータスRanToCompletionを持っている場合は、"いくつかの作業"が行われます:私はFinalWorkがある冗長な変数tasksTaskContinuationOptions.OnlyOnRanToCompletion

var taskA = Task.Factory.StartNew(WorkA); 
var taskB = Task.Factory.StartNew(WorkB); 
var allTasks = new[] { taskA, taskB }; 
Task.Factory.ContinueWhenAll(allTasks, FinalWork); 

を除去することによって、自分のコードを変更しました。すべてのタスクが完了した直後に実行され、メインタスクをブロックしません。 少なくとも1つのタスクをキャンセルすると、何も行われません。

また、あなたがこれを行うことができます

var taskA = Task.Factory.StartNew(WorkA); 
var taskB = Task.Factory.StartNew(WorkB); 
var allTasks = new[] { taskA, taskB }; 
var continuedTask = Task.WhenAll(allTasks).ContinueWith((antecedent) => { /*Do Work*/ }, TaskContinuationOptions.OnlyOnRanToCompletion)); 
3

完了までに実行されたタスクを実行するコードは提供されていません(tasks変数は無視されます)。 TaskContinuationOptions.OnlyOnRanToCompletionを削除するだけで同じ結果が得られます。つまり、の場合、ContinueWhenAllTaskContinuationOptions.OnlyOnRanToCompletionと使用すると、すべてのタスクが完了するか失敗するまで続行が呼び出されません。完了したタスクだけで何もしない場合は、Task.Factory.ContinueWhenAll(allTasks, tasks => FinalWork());

と同じです。もっと具体的なことがあれば、誰かがあなたを助けることができるように詳細を提供してください。あなたが実際にあなたの質問に質問を自分で答え

var taskA = Task.Factory.StartNew(WorkA); 
    var taskB = Task.Factory.StartNew(WorkB); 
    var allTasks = new[] { taskA, taskB }; 

    taskA.Wait(); 
    taskB.Wait(); 

    if (taskA.Status == TaskStatus.RanToCompletion && taskB.Status == TaskStatus.RanToCompletion) 
     Task.Factory.ContinueWhenAll(allTasks, tasks => FinalWork()); 
    else 
     //do something 

My question is how to check that all tasks have done their work properly (all tasks statuses are RanToCompletion) and then do FinalWork()? In the meantime, the application performs other tasks.

少なくともそれは私が質問は、次のコードをチェックして読んだものです:あなたが提起実際の質問に答えるために

+0

はい、そうです。今、変数 'tasks'が冗長であることがわかります。タスクの状態に関するすべての情報は、変数 'allTask​​s'を介して関数に渡すことができます。 – Zen

1

もしあなたがそれを意味したら。

+0

答えていただきありがとうございます。残念ながら、この解決策は、タスク 'メソッドを使用してメインタスクをブロックしています。Wait' – Zen

+0

@Zenタスクの宣言と待機の間にいくつかのタスクを追加しました。これらのタスクは、後であなたの問題を後で再調査します。 –

+0

@Zen:新しいクラスを追加し、スレッドを含んでいて、すべてうまく動作します。何もロックされておらず、すべてがスムーズに動いています。私は今までのところ問題がないので、あなたの問題に関するさらに詳しい情報が必要になります。基本的にコンストラクタにスレッドを開始するクラスを追加し、タスクの前に追加しました。 'code' var taskC = Task.Factory.StartNew(WorkC); JustAnotherThread jt = new JustAnotherThread(); var taskA = Task.Factory.StartNew(WorkA); 'code' –