未处理未处理的异常处理程序的Metro/WinRT UI异步void事件处理程序

Sea*_*ett 13 async-await c#-5.0 microsoft-metro windows-8 windows-runtime

请考虑以下内容从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();
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,给定具有两个按钮及其单击事件处理程序的Metro UI,唯一的区别是第二个事件处理程序被标记为async.

然后单击每个按钮,我希望在两种情况下都能调用UnhandledException处理程序,因为它们(应该)都是通过UI线程和相关的同步上下文输入的.我的理解是,对于async void方法,应该通过初始同步上下文捕获和"重新抛出"(保留原始堆栈跟踪)的任何异常,这也在Async/Await FAQ中明确说明.

但是在这种情况下调用UnhandledException处理程序async,因此应用程序崩溃了!由于这会挑战我认为非常直观的模型,我需要知道原因!是的,我知道我可以将处理程序的主体包装在一个try { } catch { },但我的问题是为什么不调用逆止器UnhandledException处理程序?

为了进一步强调为什么这没有意义,请考虑以下几乎相同的WPF应用程序摘录,同时使用async/await并以.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();
    }

    private async void Button_Click_2(object sender, RoutedEventArgs e)
    {
        throw new NotSupportedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

[WPF同时具有Application DispatcherUnhandledException事件处理程序以及AppDomain UnhandledException事件处理程序,但有一个细微差别,但您只能将DispatcherUnhandledException中的异常标记为'processed',它与Metro/WinRT Application UnhandledException事件处理程序一致以上.]

然后点击每个按钮时,DispatcherUnhandledException处理器的确是叫这两种情况下,如预期,应用程序也不会崩溃.

Pie*_*i K 5

这里回答:没有从异步事件回调中触发UnhandledException

这是WinRT的已知限制.希望它能在下次更新中得到修复.


Tho*_*mas 5

以下帖子中的解决方案为我工作,只做了一个小改动:我不得不移动AsyncSynchronizationContext.Register(); 到App.OnLaunched活动

http://www.markermetro.com/2013/01/technical/handling-unhandled-exceptions-with-asyncawait-on-windows-8-and-windows-phone-8/