我正在编写应根据先前任务的成功或失败执行的任务序列。但是,其中一个任务意外执行,即使它的前期任务没有执行。
步骤是,我导入一些数据。如果成功,我会启动保存,然后计算。如果导入失败,我想处理异常。
这是我用以下代码重现的最简单的代码:
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();
这个输出是:
进口
计算值
错误
FAIL
我认为calcTask应该在saveTask之后执行。但是即使saveTask没有执行它也会执行。有趣的是,在calcTask中,task.IsCanceled == true。
为什么calc任务正在执行?
答案 0 :(得分:2)
我相信你必须添加
TaskContinuationOptions.OnlyOnRanToCompletion
每个后续项目,以确保它们不会运行,除非前提条件运行完成,否则它是公平的游戏,它将简单地按顺序运行天气失败或运行。
我用过这个,似乎按你的意愿回应。
var calcTask = saveTask.ContinueWith(task =>
{
Console.WriteLine("calc");
}, TaskContinuationOptions.OnlyOnRanToCompletion);
答案 1 :(得分: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.NotOnFaulted
上使用calcTask
将无效,因为saveTask
不会抛出任何异常。必须使用TaskContinuationOptions.OnlyOnRanToCompletion指定只有在calcTask
正确执行时才应执行saveTask
。您可以在TaskContinuationOptions
上找到有关{<1}}的更多信息: