如何检查所有任务是否已正确完成?

时间:2012-09-03 13:28:10

标签: c# multithreading .net-4.0 task task-parallel-library

我的代码中有以下几行:

    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()? 与此同时,应用程序执行其他任务。

3 个答案:

答案 0 :(得分:11)

根据@Peter Ritchie和@Ben McDougall的答案,我找到了一个解决方案。我通过删除冗余变量tasksTaskContinuationOptions.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状态为RanToCompletion“有些工作”将会完成。它将在所有任务完成后立即执行,不会阻止主任务。 如果我取消至少一项任务,则不会做任何事情。

或者你可以这样做,

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));

答案 1 :(得分:3)

您尚未提供任何代码,可以对任何运行完成的任务执行任何操作(忽略您的tasks变量)。如果您只是删除TaskContinuationOptions.OnlyOnRanToCompletion,则会得到相同的结果。即如果可以使用ContinueWhenAll TaskContinuationOptions.OnlyOnRanToCompletion,则在所有任务完成或失败之前不会调用您的继续。如果您对完成的任务不执行任何操作,则与Task.Factory.ContinueWhenAll(allTasks, tasks => FinalWork());

相同

如果您想要做更具体的事情,请提供详细信息,以便有人可以帮助您。

答案 2 :(得分: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

如果你的意思是这样的话,你实际上是自己回答了这个问题。