WPF如何处理异常并继续

pat*_*gle 9 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;
}
Run Code Online (Sandbox Code Playgroud)

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

    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");
    }
Run Code Online (Sandbox Code Playgroud)

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

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

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

Pet*_*iho 6

坦白说,我认为您的整个设计是一个坏主意。在我看来,您希望能够通过记录这些异常并让您的程序继续执行来“处理”这些异常。但这是一种极其危险的方法,绝对不建议这样做。您应该只捕获并处理异常你该知道事先什么例外的是什么安全的方法来处理它。

否则会冒着使程序处于未知状态的风险,从而导致从(至多)错误的行为到(至多)(永久)破坏用户重要数据状态的一切事情。

另请参见是否应捕获所有异常?

但是,假设您仍然要执行此操作,则您将无法使用该LogUnhandledException()方法Handled在事件args中设置属性,因为每个事件都是不同的。仅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();
     };
}
Run Code Online (Sandbox Code Playgroud)