我正在尝试在使用MVVM Light Toolkit构建的WPF应用程序中创建一个简单的全局异常处理程序,但我很难让它工作。
问题是视图模型中出现的异常不会在App的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;
}
我发现this blog post描述了问题点,使用此代码描述的解决方案剪切了视图模型:
// Throw the exception in the UI thread.
App.Current.RootVisual.Dispatcher.BeginInvoke(() => { throw new MyException(); });
但是,我希望所有异常都冒泡到全局异常处理程序,而不仅仅是我自己在VM中抛出的异常处理程序。
所以问题是:在某个地方以某种方式将异常从其他线程重新引入UI线程吗?
更新:为应用的事件处理程序设置添加了更详细的代码。
答案 0 :(得分:6)
我想我现在想出来了。
问题是由于WPF抑制了视图数据绑定中抛出的异常,并且因为我的视图模型被数据绑定到视图的DataContext(通过我的 ViewModelLocator 中的属性利用unity依赖注入器)将吞下视图模型构造中的任何异常。
有关详细信息,请参阅this SO question。
所以我想我必须确保在构造函数中没有任何重要的应用程序能够正常运行。
答案 1 :(得分:1)
WPF和Windows窗体应用程序的“全局”异常处理事件(Application.DispatcherUnhandledException和Application.ThreadException)仅针对主UI线程上引发的异常触发。您仍然必须手动处理工作线程上的异常。
AppDomain.CurrentDomain.UnhandledException触发任何未处理的异常,但无法阻止应用程序在之后关闭。
How do I invoke a method on the UI thread when using the TPL?