6

我正在尝试在使用 MVVM Light Toolkit 构建的 WPF 应用程序中创建一个简单的全局异常处理程序,但我很难让它工作。

问题是视图模型中出现的异常不会被应用程序的 UnhandledException 处理程序捕获,即使我像这样为 Dispatcher 和 AppDomain 注册了一个侦听器:

private void Application_Startup(object sender, StartupEventArgs e)
{
   AppDomain.CurrentDomain.UnhandledException += DomainUnhandledException;
   DispatcherUnhandledException += App_DispatcherUnhandledException;
}

private void DomainUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
{
   var exception = unhandledExceptionEventArgs.ExceptionObject as Exception;
   ShowExceptionMessage(exception);
}
private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
   ShowExceptionMessage(e.Exception);
   e.Handled = true;
}

我发现这篇博客文章描述了问题点,并为视图模型截取了这段代码描述的解决方案:

// Throw the exception in the UI thread.
App.Current.RootVisual.Dispatcher.BeginInvoke(() => { throw new MyException(); });

但是,我希望所有异常都冒泡到全局异常处理程序中,而不仅仅是那些我自己扔进 VM 中的异常。

所以问题是:是否有可能以某种方式将其他线程的异常重新抛出到一个地方的 UI 线程中?

更新:为应用程序的事件处理程序设置添加了更详细的代码。

4

2 回答 2

7

我想我现在想通了。

问题是由于 WPF 抑制了视图数据绑定中引发的异常,并且因为我的视图模型数据绑定到视图的 DataContext(通过我的ViewModelLocator中的属性使用统一依赖注入器),视图模型构造中的任何异常都会被吞噬。

有关更多信息,请参阅此 SO 问题

所以我想我只需要确保在构造函数中不会发生对应用程序正常运行能力重要的事情。

于 2012-06-01T09:55:20.763 回答
1

WPF 和 Windows 窗体应用程序(Application.DispatcherUnhandledException 和 Application.ThreadException)的“全局”异常处理事件仅对主 UI 线程上抛出的异常触发。您仍然必须手动处理工作线程上的异常。

AppDomain.CurrentDomain.UnhandledException 触发任何未处理的异常,但不提供阻止应用程序随后关闭的方法。

  • 也许还要检查线程池“分而治之”的风格。
  • TPL

使用 TPL 时如何在 UI 线程上调用方法?

于 2012-05-31T13:00:30.957 回答