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“一些工作”将会完成。它会在所有任务完成后立即执行,不会阻塞主任务。如果我至少取消其中一项任务,则什么也做不了。

或者,您可以这样做,

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。即,如果您可以使用您的延续ContinueWhenAllTaskContinuationOptions.OnlyOnRanToCompletion则在所有任务完成或失败之前不会被调用。如果您只对已完成的任务不做任何事情,那与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 回答