请考虑以下内容,从
Windows 8 Metro / WinRT应用程序中提取,这些应用程序已经减少到显示异常所需的最低限度:
public class App : Application { public App() { UnhandledException += (sender,e) => e.Handled = true; } } public class MainPage : Page { private void Button_Click_1(object sender,RoutedEventArgs e) { throw new NotSupportedException(); } private async void Button_Click_2(object sender,RoutedEventArgs e) { throw new NotSupportedException(); } }
所以给出一个带有两个按钮和他们的点击事件处理程序的Metro UI,唯一的区别是第二个事件处理程序被标记为异步.
然后单击每个按钮,我会期望在这两种情况下调用UnhandledException处理程序,因为它们(应该)都通过UI线程和关联的同步上下文输入.
我的理解是,对于异步void方法,应该通过初始同步上下文捕获任何异常并重新抛出(保留原始堆栈跟踪),这在Async / Await FAQ中也是清楚的.
但是UnhandledException处理程序在异步情况下不被调用,所以应用程序崩溃!由于这是挑战我认为其他非常直观的模式,我需要知道为什么!是的,我知道我可以在try {} catch {}中包装处理程序的正文,但是我的问题是为什么不支持UnhandledException处理程序?
为了进一步强调为什么没有意义,请考虑WPF应用程序的以下实际相同的提取,也使用异步/等待和目标.NET Framework 4.5:
public class App : Application { public App() { DispatcherUnhandledException += (sender,e) => e.Handled = true; } } public class MainWindow : Window { private void Button_Click_1(object sender,RoutedEventArgs e) { throw new NotSupportedException(); } }
[有一个微妙的区别,WPF有一个Application DispatcherUnhandledException事件处理程序以及一个AppDomain UnhandledException事件处理程序,但是您只能在DispatcherUnhandledException中将异常标记为“已处理”,它们与Metro / WinRT Application UnhandledException事件处理程序对齐以上.]
然后单击每个按钮,DispatcherUnhandledException处理程序确实在这两种情况下按预期方式调用,并且应用程序不会崩溃.
这里回答:
No UnhandledException fired from async event callback
原文链接:/windows/371234.html这是WinRT的已知限制.我们希望,它被固定在下次更新.