1

我正在编写应根据先前任务的成功或失败执行的任务序列。但是,其中一项任务意外执行,即使其先前的任务没有执行。

步骤是,我导入一些数据。如果成功,我会开始保存,然后进行计算。如果导入失败,我想处理异常。

这是我可以重现的最简单的代码:

var importTask = new Task(() => {
   Console.WriteLine("import");
   // Force an exception
   throw new Exception("FAIL");
});

var saveTask = importTask.ContinueWith(task => {
   Console.WriteLine("save");
}, TaskContinuationOptions.NotOnFaulted);

var calcTask = saveTask.ContinueWith(task => {
   Console.WriteLine("calc");
});

var errorTask = importTask.ContinueWith(task => {
   Console.WriteLine("error");
   Console.WriteLine(task.Exception.InnerException.Message);
}, TaskContinuationOptions.OnlyOnFaulted);

importTask.Start();

输出是:

进口

计算

错误

失败

我认为 calcTask 应该在 saveTask 之后执行。但是,即使 saveTask 没有执行,它也会执行。有趣的是,在 calcTask 中,task.IsCanceled == true。

为什么执行 calc 任务?

4

2 回答 2

2

我相信你必须添加

TaskContinuationOptions.OnlyOnRanToCompletion

到每个后续项目,以确保它们不会运行,除非先行项运行到完成,否则这是公平的游戏,它将简单地按顺序运行,无论它失败或运行。

我使用了它,它似乎按照您的意愿响应。

var calcTask = saveTask.ContinueWith(task =>
{
     Console.WriteLine("calc");
}, TaskContinuationOptions.OnlyOnRanToCompletion);
于 2013-07-31T04:32:38.777 回答
1

用这个:

var importTask = new Task(() =>
{
    Console.WriteLine("import");
    // Force an exception
    throw new Exception("FAIL");
});

var saveTask = importTask.ContinueWith(task =>
{
    Console.WriteLine("save");
}, TaskContinuationOptions.NotOnFaulted);

var calcTask = saveTask.ContinueWith(task =>
{
    Console.WriteLine("calc");
}, TaskContinuationOptions.OnlyOnRanToCompletion);

var errorTask = importTask.ContinueWith(task =>
{
    Console.WriteLine("error");
    Console.WriteLine(task.Exception.InnerException.Message);
}, TaskContinuationOptions.OnlyOnFaulted);

使用TaskContinuationOptions.NotOnFaultedoncalcTask将不起作用,因为saveTask不会引发任何异常。您必须使用 TaskContinuationOptions.OnlyOnRanToCompletion 来指定只有在正确执行的calcTask情况下才应该执行saveTask。您可以找到有关以下方面的更多信息TaskContinuationOptions

http://msdn.microsoft.com/en-us/library/ee372288.aspx

于 2013-07-31T04:46:52.077 回答