在button_click
事件中,我开始Task
以异步方式进行一些耗时的计算。我使用Task.ContinueWith
并将TaskSheduler设置为继续使用UI同步上下文,以在Textbox
中显示异步计算的结果。
现在让我们说最后一部分抛出一个像这样的例外:
private void button1_Click(object sender, EventArgs e)
{
Task.Factory.StartNew(DoSomeCalculations).ContinueWith
(t => { throw new Exception("Some Exception"); }, TaskScheduler.FromCurrentSynchronizationContext());
}
如果我启用调试选项“启用我的代码”,程序将停止并收到警告:“用户代码未处理异常”
但是如果我没有设置这个选项,Exception就会消失(没有程序崩溃,什么都没有)。
那么我如何/在哪里处理这个例外?
编辑:请注意,正如标记所示,我使用的是.NET-4.0
答案 0 :(得分:1)
如果你想处理异常,那么在continuation本身内部有一个try / catch块,这样它就可以处理它自己的异常,或者为继续处理异常添加一个额外的延续。
请注意,如果您使用ContinueWith
而不是{{1}}来添加延续,那么它通常会更简单,特别是在处理异常时,因为它会代表您添加延续。
答案 1 :(得分:1)
如果您使用的是.NET Framework 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
答案 2 :(得分:0)
根据最佳实践,如果我们无法避免使用async void方法(特别是对于事件处理程序),则应该在该方法中实现try catch。但是你需要确保你调用的所有异步方法都有异步的Task方法签名,以便捕获抛出的异常。