【问题标题】:Catching Exceptions in WPF at the FrameWork Level在框架级别捕获 WPF 中的异常
【发布时间】:2011-06-05 06:41:55
【问题描述】:

我正在开发一个轻量级的 WPF MVVM 框架,并且希望能够捕获未处理的异常,并在理想情况下从中恢复。

暂时忽略所有不这样做的好论据,我遇到以下情况:

如果我在 App.xaml.cs 的 OnStartup 方法中注册 AppDomain.CurrentDomain.UnhandledException 的处理程序,如下...

App.xaml.cs:

protected override void OnStartup(StartupEventArgs e)
{
  AppDomain.CurrentDomain.UnhandledException += new
     UnhandledExceptionEventHandler(this.AppDomainUnhandledExceptionHandler); 

  base.OnStartup(e);
}


 void AppDomainUnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs ea)
{
  Exception e = (Exception)ea.ExceptionObject;
  // log exception
}

然后在我的一个虚拟机中引发异常,处理程序按预期调用。

到目前为止一切顺利,除了我无法使用这种方法恢复之外,我所能做的就是记录异常,然后让 CLR 终止应用程序。

我真正想做的是恢复并将控制权返回给主框架 VM。 (再次抛开反对这样做的动机)。

所以,读了一些资料,我决定在同一个地方为 AppDomain.CurrentDomain.UnhandledException 注册一个事件处理程序,这样代码现在看起来像这样......

protected override void OnStartup(StartupEventArgs e)
{
  AppDomain.CurrentDomain.UnhandledException += 
    new UnhandledExceptionEventHandler(this.AppDomainUnhandledExceptionHandler); 

  this.DispatcherUnhandledException += 
    new DispatcherUnhandledExceptionEventHandler(DispatcherUnhandledExceptionHandler);

  base.OnStartup(e);
}

void AppDomainUnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs ea)
{
  Exception e = (Exception)ea.ExceptionObject;
  // log exception
}

void DispatcherUnhandledExceptionHandler(object sender, DispatcherUnhandledExceptionEventArgs args)
{
  args.Handled = true;
  // implement recovery
}

问题是,一旦我为 this.DispatcherUnhandledException 注册了处理程序,就不会调用任何事件处理程序。因此,注册 DispatcherUnhandledExceptionHandler 会以某种方式停用 AppDomain.CurrentDomain.UnhandledException 的处理程序。

有没有人有办法捕获未处理的 VM 异常并从中恢复?

值得一提的是,框架中没有明确使用线程。

【问题讨论】:

    标签: c# wpf exception-handling c#-4.0


    【解决方案1】:

    VS 向您显示异常的原因是因为您已将其设置为这样(您明确地执行了此操作,或者 - 更有可能 - VS 中的默认设置是这样配置的)。您可以通过Debug->Exceptions 菜单控制Visual Studio 在调试代码中遇到异常时的操作。

    你甚至可以让它坏掉,即使你有一个陷阱,这在某些情况下非常方便。

    如果您不使用多线程,那么 DispatcherUnhandledException 事件应该没问题,因为它会捕获主 UI 线程上未捕获的所有内容。

    【讨论】:

    • 感谢 Isak,重要的是要知道我将捕获所有可能产生的异常。
    【解决方案2】:

    快速回答我自己的问题:

    这行得通...

    App.xaml.cs:

    protected override void OnStartup(StartupEventArgs e)
    {
      Application.Current.DispatcherUnhandledException +=
        new DispatcherUnhandledExceptionEventHandler(DispatcherUnhandledExceptionHandler);
    
      base.OnStartup(e);
    }
    
    void DispatcherUnhandledExceptionHandler(object sender, DispatcherUnhandledExceptionEventArgs args)
    {
      args.Handled = true;
      // implement recovery
      // execution will now continue...
    }
    

    [编辑:我下面的 cmets 与实现无关,但我的特定 IDE (Visual Studio) 配置与 IDE 捕获异常有关。请参阅上面 Isak 的 cmets。]

    但是,这是一个很大的问题,但是,如果您在 VisualStudio 中执行,那么您仍然会弹出 VS 异常通知对话框,并且只有在您按 F5/继续时才会调用 DispatcherUnhandledExceptionHandler,之后执行将照常继续。

    如果您直接运行编译后的二进制文件,即从命令行或通过 Windows 资源管理器,则将按照您的预期调用处理程序,而不会出现任何中间弹出窗口。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-27
      • 2015-10-28
      • 1970-01-01
      • 2023-03-14
      • 2018-07-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多