WPF如何处理异常并继续

时间:2017-08-26 13:48:37

标签: c# wpf

我最初有代码来处理DispatcherUnhandledException,它会记录错误并将异常标记为已处理

protected override void OnStartup(StartupEventArgs e)
{
    Dispatcher.UnhandledException += OnDispatcherUnhandledException;
}
...
void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
    // Log Error here
    e.Handled = true;
}

我试图通过涵盖更广泛的未处理异常来改善这一点

    protected override void OnStartup(StartupEventArgs e)
    {
         AppDomain.CurrentDomain.UnhandledException += (s, ex) =>
         LogUnhandledException((Exception)ex.ExceptionObject, 
        "AppDomain.CurrentDomain.UnhandledException");

         DispatcherUnhandledException += (s, ex) =>
         LogUnhandledException(ex.Exception, 
         "Application.Current.DispatcherUnhandledException");

         TaskScheduler.UnobservedTaskException += (s, ex) =>
         LogUnhandledException(ex.Exception, 
         "TaskScheduler.UnobservedTaskException");
    }

但我无法使用此事件处理异常

    private void LogUnhandledException(Exception e, string @event)
    {
      // Log Error here
      e.Handled = true; //Doesn't work
    }

如何处理所有类型的异常,以便代码继续尝试?

1 个答案:

答案 0 :(得分:4)

坦率地说,在我看来,你的整个设计都是个坏主意。在我看来,你希望能够处理"通过记录它们并让程序继续执行来实现这些异常。但这是一种非常危险的方法,绝对不推荐。您应该事先捕获并处理您知道的异常,异常是什么以及处理它的安全方法是什么。

否则就是冒着将程序置于未知状态的风险,导致从(最好)有缺陷的行为到(最坏的情况)永久性地破坏用户重要数据的状态。

另见Should you catch all exceptions?

但是,假设您无论如何都要这样做,那么您将无法使用LogUnhandledException()方法在事件args中设置Handled属性,因为每个事件都是不同的。只有DispatcherUnhandledException事件才能设置Handled属性。 UnobservedTaskException有一个Observed属性,您可以设置,AppDomain.UnhandledException事件甚至没有类似的属性。

但是,您当然可以专门处理每个处理程序。例如:

protected override void OnStartup(StartupEventArgs e)
{
     AppDomain.CurrentDomain.UnhandledException += (s, ex) =>
     LogUnhandledException((Exception)ex.ExceptionObject, 
    "AppDomain.CurrentDomain.UnhandledException");

     DispatcherUnhandledException += (s, ex) =>
     {
         LogUnhandledException(ex.Exception, 
         "Application.Current.DispatcherUnhandledException");
         ex.Handled = true;
     };

     TaskScheduler.UnobservedTaskException += (s, ex) =>
     {
         LogUnhandledException(ex.Exception, 
         "TaskScheduler.UnobservedTaskException");
         ex.SetObserved();
     };
}