Metro/WinRT UI 异步无效事件处理程序未调用未处理的异常处理程序 [英] Unhandled exception handler not called for Metro / WinRT UI async void event handler

查看:42
本文介绍了Metro/WinRT UI 异步无效事件处理程序未调用未处理的异常处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

将以下内容视为 Windows 8 Metro/WinRT 应用程序的摘录,这些内容已减少到显示异常所需的最低限度:

Consider the following to be extracts from a Windows 8 Metro / WinRT app, which have been reduced to the bare minimum required to show the anomaly:

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,唯一的区别是第二个事件处理程序标记为 async.

So given a Metro UI with two buttons and their click event handlers, the only difference is that the second event handler is marked as async.

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

Then clicking on each button, I would expect the UnhandledException handler to be called in both cases, since they (should) both be entered via the UI thread and associated synchronization context. My understanding is that, for async void methods, any exceptions should be captured and 'rethrown' (preserving the original stacktrace) via the initial synchronization context, which is also clearly stated in the Async / Await FAQ.

但是 UnhandledException 处理程序在 async 的情况下没有被调用,所以应用程序崩溃了!由于这挑战了我认为非常直观的模型,我需要知道为什么!是的,我知道我可以将处理程序的主体包装在 try { } catch { } 中,但我的问题是为什么不调用 backstop UnhandledException 处理程序?

But the UnhandledException handler is not called in the async case, so the application crashes! Since this challenges what I consider an otherwise very intuitive model, I need to know why! Yes, I know I could wrap the body of the handler in a try { } catch { }, but my question is why isn't the backstop UnhandledException handler called?

为了进一步强调为什么这没有意义,请考虑以下实际上相同的 WPF 应用摘录,也使用 async/await 并针对 .NET Framework 4.5:

To further emphasise why this doesn't make sense, consider the following practically identical extracts from a WPF app also using async / await and targeting .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();
    }
}

[有一个细微的区别,即 WPF 既有 Application DispatcherUnhandledException 事件处理程序,也有 AppDomain UnhandledException 事件处理程序,但您只能在 DispatcherUnhandledException 中将异常标记为已处理",这与 Metro/WinRT 应用程序一致上面的 UnhandledException 事件处理程序.]

[There is a subtle difference that WPF has both an Application DispatcherUnhandledException event handler as well as an AppDomain UnhandledException event handler, but you can only mark the exception as 'handled' in the DispatcherUnhandledException, which aligns with the Metro / WinRT Application UnhandledException event handler above.]

然后点击每个按钮,DispatcherUnhandledException 处理程序确实在两种情况下被调用,正如预期的那样,并且应用程序不会不会崩溃.

Then clicking on each button, the DispatcherUnhandledException handler is indeed called in both cases, as expected, and the application does not crash.

推荐答案

以下帖子中的解决方案对我有用,只有一个小改动:我不得不移动 AsyncSynchronizationContext.Register();到 App.OnLaunched 事件

The solution in the following post worked for me, with one small change: I had to move AsyncSynchronizationContext.Register(); to the App.OnLaunched event

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

这篇关于Metro/WinRT UI 异步无效事件处理程序未调用未处理的异常处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆