8

コードに次の行があります。

    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が原因です。

私の質問は、すべてのタスクが適切に作業を行ったことを確認し (すべてのタスクのステータスがRanToCompletion )、それからFinalWork()を実行する方法です。その間、アプリケーションは他のタスクを実行します。

4

3 に答える 3

13

@Peter Ritchie と @Ben McDougall の回答に基づいて、解決策を見つけました。tasks冗長な変数を削除してコードを変更し、TaskContinuationOptions.OnlyOnRanToCompletion

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

どこFinalWorkにある:

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

すべてtasksに status がある場合RanToCompletion「いくつかの作業」が行われます。すべてのタスクが完了した直後に実行され、メイン タスクをブロックしません。少なくとも 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));
于 2012-09-04T08:26:22.280 に答える
3

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

より具体的にやりたいことがある場合は、誰かがあなたを助けることができるように、詳細を提供してください.

于 2012-09-03T14:24:04.027 に答える
1

あなたが提起した実際の質問に答えるには:

私の質問は、すべてのタスクが適切に機能したことを確認し (すべてのタスクのステータスが RanToCompletion である)、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

あなたがそれを意味したのであれば、あなたは実際にあなたの質問で自分自身で質問に答えました。

于 2012-09-03T15:19:04.670 に答える