简体   繁体   中英

WPF how to handle Exceptions and continue

I originally had code to handle DispatcherUnhandledException which would log the error and mark the exception as handled

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

I've tried to improve this by covering a wider range of unhandled exceptions

    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");
    }

but I cannot handle the exceptions using this event

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

How can I handle all types of exceptions here so the code will attempt to continue?

Frankly, your entire design is a bad idea, in my opinion. It appears to me that you want to be able to "handle" these exceptions by logging them and letting your program continue executing. But that's an incredibly dangerous approach and definitely not recommended. You should only catch and handle exceptions for which you know in advance what the exception is and what the safe way to handle it is.

To do otherwise is to risk leaving your program in an unknown state, leading to anything from (at best) buggy behavior to (at worst) permanently corrupting the state of user's important data.

See also Should you catch all exceptions?

But, assuming you're going to do this anyway, you're not going to be able to use the LogUnhandledException() method to set the Handled property in the event args, because each of those events is different. Only the DispatcherUnhandledException event even has a Handled property to set. The UnobservedTaskException has an Observed property which you can set, and the AppDomain.UnhandledException event doesn't even have an analogous property.

However, you can of course specialize each handler to do that. For example:

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();
     };
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM