我有几个使用Task.Factory.StartNew启动的链式任务(...
经过一些严重的疼痛,他们运行得很好。现在我要回去尝试为Tasks添加更好的错误检查,因为这是让任务正常工作的痛苦。我创建了一个小型WPF应用程序,仅用于测试一项任务并尝试捕获错误。我有这个作为“最后的度假胜地”的错误陷阱。
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
但是,我想在此之前捕获错误并尝试优雅地处理它们。
测试这个小任务:
Task[] tasks = new Task[1];
MessageBox.Show("Before Tasks");
tasks[0] = Task.Factory.StartNew(DoBackgroundTask).ContinueWith(
w =>
{
MessageBox.Show("OnlyOnRanToCompletion");
}
, token, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler);
后台任务如下(一行测试成功,另一行测试失败。注释取决于我正在处理的内容):
private void DoBackgroundTask()
{
var two = 1 + 1;
//throw new Exception("Test");
}
我在任务StartNew之后进行等待和错误检查只是为了暂停并允许我在进入TaskScheduler_UnobservedTaskException之前捕获错误
try
{
tasks[0].Wait();
}
catch (AggregateException aex)
{
Messages.inform(aex.InnerException.Message);
}
我可能误解了处理任务/线程错误的正确方法,但这是我的问题:
1)当我使用除None之外的任何其他任务继续选项时。我的ContinueWith代码未执行。我真的想在取消/故障/没有跑完成时做点什么。
2)不确定task.Wait()和TaskContinuation方法是否是陷阱和处理错误的最佳方法,但我找不到另一种方法。
3)我想链接我的任务延续选项。例如。处理OnlyOnRanToCompletion的代码片段和处理NotOnRanToCompletion的另一部分。我似乎无法让他们一起工作。
简而言之,使用taskContinuationOptions.None以及task.Wait()之外的任何东西,catch aggregateexception似乎都有效。
所有其他的悬念......
我是这样做错的?
谢谢!
更新 - 此作品:
tasks[0] = Task.Factory.StartNew(DoBackgroundTask);
tasks[1] = tasks[0].ContinueWith(
ant =>
{
// Check task status.
switch (tasks[0].Status)
{
// Handle any exceptions to prevent UnobservedTaskException.
case TaskStatus.RanToCompletion:
// do stuff
break;
case TaskStatus.Faulted:
if (tasks[0].Exception != null)
Messages.inform(tasks[0].Exception.InnerException.Message);
else
Messages.inform("Operation failed!");
break;
default:
break;
}
}
);
似乎就像我做的那样。继续关闭主要任务的StartNew它似乎不能很好地工作。当我创建第二个任务时,使用.ContinueWith创建第一个任务...我们正在开展业务。我真的不明白其中的区别。看起来他们都应该工作。