0

在一个button_click事件中,我开始Task异步进行一些耗时的计算。我使用Task.ContinueWithTaskSheduler 并将其设置为延续到 UI 同步上下文,以在Textbox.

现在让我们说最后一部分抛出一个异常,如下所示:

private void button1_Click(object sender, EventArgs e)
{
   Task.Factory.StartNew(DoSomeCalculations).ContinueWith
      (t => { throw new Exception("Some Exception"); }, TaskScheduler.FromCurrentSynchronizationContext()); 
}

如果我启用调试选项“仅启用我的代码”,则程序会停止并收到警告:“用户代码未处理异常”

但是如果我不设置这个选项,异常就会消失在任何地方(没有程序崩溃,什么都没有)。

那么如何/在哪里可以处理这个异常?

编辑:请注意,正如标签所示,我使用的是 .NET-4.0

4

3 回答 3

1

如果要处理异常,则要么在延续本身内部有一个 try/catch 块,以便它处理自己的异常,要么在延续中添加一个额外的延续来处理异常。

请注意,如果您使用await而不是ContinueWith添加延续,它通常更简单,特别是在处理异常时,因为它将代表您添加延续。

于 2016-03-09T18:22:38.380 回答
1

如果您使用的是 .NET 框架 4.5,则有一种处理 Task 对象的新方法。

private async void button1_Click(object sender, EventArgs e)
{
   await Task.Run(() =>
   {
       DoSomethingAsync()
   });
   //this line will run in UI thread
   throw new Exception("Some Exception");
}

请注意,当您使用 async 关键字时,Task 对象内发生的任何异常都会被编译器创建的状态机吞没。但是这个异常是在 Task 对象中设置的,所以基本上你仍然可以使用 Task 对象来引用异常。

供您参考:http: //blog.stephencleary.com/2012/02/async-and-await.html

于 2016-03-09T18:29:13.160 回答
0

根据最佳实践,如果我们无法避免使用 async void 方法(尤其是对于事件处理程序),则应在该方法中实现 try catch。但是您需要确保您调用的所有异步方法都具有异步任务方法签名,以便捕获抛出的异常。

于 2016-03-09T18:34:42.177 回答