Wpf MVVM轻型应用程序的全局异常处理程序
我试图在使用MVVM Light Toolkit构建的WPF应用程序中创建一个简单的全局异常处理程序,但我很难让它正常工作 问题是,视图模型中出现的异常不会被应用程序的未处理异常处理程序捕获,即使我为Dispatcher和AppDomain注册了一个侦听器,如下所示:Wpf MVVM轻型应用程序的全局异常处理程序,wpf,exception-handling,mvvm-light,Wpf,Exception Handling,Mvvm Light,我试图在使用MVVM Light Toolkit构建的WPF应用程序中创建一个简单的全局异常处理程序,但我很难让它正常工作 问题是,视图模型中出现的异常不会被应用程序的未处理异常处理程序捕获,即使我为Dispatcher和AppDomain注册了一个侦听器,如下所示: private void Application_Startup(object sender, StartupEventArgs e) { AppDomain.CurrentDomain.UnhandledException
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线程中
更新:为应用程序的事件处理程序设置添加了更详细的代码。WPF和Windows窗体应用程序(Application.DispatcherUnandledException和Application.ThreadException)的“全局”异常处理事件仅针对主UI线程上引发的异常触发。您仍然必须手动处理工作线程上的异常 AppDomain.CurrentDomain.UnhandledException在任何未处理的异常上激发,但无法防止应用程序随后关闭
- 也许还可以检查线程池的“分而治之”风格
- 第三方物流
我想我现在明白了 问题在于WPF抑制视图数据绑定中抛出的异常,并且由于我的视图模型是数据绑定到视图的DataContext的(通过使用unity dependency injector的ViewModelLocator中的属性),因此视图模型构造中的任何异常都将被忽略 有关更多信息,请参阅
因此,我想我只需要确保构造函数中不会发生对应用程序正常运行能力重要的事情。是的,我知道DispatcherUnhandledException用于UI线程异常,AppDomain的UnhandledException用于任何未处理的异常。问题是,它们中没有一个捕捉到我在VM中的命令处理程序中引发的任何异常。MVVM Light的线程是否有某种“全局异常处理程序”,或者我是否必须将所有命令处理程序包装在一个try-catch块中?实际上,如果我在数据绑定命令中抛出异常,它确实会出现在调度程序的异常处理程序中。请看我对这个问题的评论。很抱歉,在提出这个问题之前,我显然没有对这个问题进行足够的调查。我测试的异常实际上是在VM构造函数中抛出的。Unity用于DI,所以问题可能是,如何在Unity创建的对象上的构造函数中处理异常?为了进一步解释,这是如何将VM绑定到视图的DataContext:
DataContext=“{Binding MyVm,Source={StaticResource Locator}}”
。定位器正在公开以下属性:public MyViewModel MyVm{get{return unitycontainer.Resolve();}}}
只有在视图已可见时,才会抑制这些属性。如果尝试显示视图,并且视图模型的绑定属性引发了异常(假设在调用show之前已设置了数据上下文),则将无法打开该窗口