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

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

问题描述

将以下内容视为从 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.

但是在 async 的情况下没有调用 UnhandledException 处理程序,所以应用程序崩溃了!由于这挑战了我认为非常直观的模型,我需要知道为什么!是的,我知道我可以将处理程序的主体包装在 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 Application上面的 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 async void 事件处理程序未调用未处理的异常处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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