http://msdn.microsoft.com/en-us/library/dd997415.aspx
根据上面引用的文章,我试图处理continuatin任务中的异常.我在上面的文章中引用的例子是这样的:
var task1 = Task.Factory.StartNew(() => { throw new MyCustomException("Task1 faulted."); }) .ContinueWith((t) => { Console.WriteLine("I have observed a {0}",t.Exception.InnerException.GetType().Name); },TaskContinuationOptions.OnlyOnFaulted);
我的代码是:
Task<string> task = Task<string>.Factory.StartNew(() => process.StartTask(this)); task.ContinueWith(CloseDialog,TaskContinuationOptions.OnlyOnFaulted);
在StartTask中,我像示例一样抛出错误.我的期望是CloseDialog将执行,我可以检查该方法中的task.Exception,如示例所示.但是,当我抛出异常时,代码只会因未处理的异常而停止.我应该使用try / catch块吗?如果是这样,在哪里?
顺便说一句,我希望我的延续任务(CloseDialog)始终运行.我只是使用.OnlyOnFaulted,因为这是示例中显示的内容.
解决方法
延续可以查明先行任务的异常属性是否由先行任务抛出异常.以下内容将NullReferenceException的结果打印到控制台
Task task1 = Task.Factory.StartNew (() => { throw null; }); Task task2 = task1.ContinueWith (ant => Console.Write(ant.Exception());
如果task1抛出异常并且延迟没有捕获/查询此异常,则认为它未处理并且应用程序死亡.使用continuation,通过Status关键字建立任务结果就足够了
asyncTask.ContinueWith(task => { // Check task status. switch (task.Status) { // Handle any exceptions to prevent UnobservedTaskException. case TaskStatus.RanToCompletion: if (asyncTask.Result) { // Do stuff... } break; case TaskStatus.Faulted: if (task.Exception != null) mainForm.progressRightLabelText = task.Exception.InnerException.Message; else mainForm.progressRightLabelText = "Operation Failed!"; default: break; } }
如果不使用continuation,则必须等待try / catch块中的任务或在try / catch块中查询任务的Result
int x = 0; Task<int> task = Task.Factory.StartNew (() => 7 / x); try { task.Wait(); // OR. int result = task.Result; } catch (AggregateException aggEx) { Console.WriteLine(aggEx.InnerException.Message); }
希望这有帮助,即使它有点晚了,你现在知道所有的一切! :]