异步异常在调试中无法捕获
问题描述
有这样一段测试代码
1: static void Main(string[] args)
2: {
3: Action funcDelegate = TestFunc;
4: funcDelegate.BeginInvoke(Done, funcDelegate);
5: Console.ReadKey();
6: }
7:
8: static void Done(IAsyncResult ar)
9: {
10: try
11: {
12: var funcDelegate = (Action)ar.AsyncState;
13: funcDelegate.EndInvoke(ar);
14: } catch(Exception e)
15: {
16: Console.WriteLine("Get the Async Excetion :{0}",e.Message);
17: }
18: }
19:
20: static void TestFunc()
21: {
22: Thread.Sleep(2000);
23: throw new Exception("TestFuncException");
24: }
首先,这段代码是没有问题的。如果想在异步调用中处理异常,必须在EndInvoke中处理。
但是如果这个时候你使用F5调试,就会提醒异常没有被处理。(VS2010亲测,VS2012似乎也没能处理这个问题)
解决方法
问题出在调试器上,他发现执行异步操作的线程栈里面没有处理方案。
所以只需要用Ctrl+F5运行就可以发现,程序实际上有捕捉到异常。
CLR有对异步调用的异常有一些特别的处理。
这里还有一个更有意思的东西,似乎部分基于EAP设计的类,出来的异步异常是可以被捕获到的。
我不清楚内部的机理