1

I have a WPF application.

I want the application to have a generic function that catches all the crashes that aren't in a try-catch block. The application shouldn't crash and stop working. Instead, it should reboot itself to try geting operational again. If it turns out the app is really messed up it shouldn't enter in an endless loop of reboots.

I tried using AppDomain.UnhandledExceptionHandler, and it really cateches the exceptions that are thrown, but after that method is executed - the program still crashes.

Is there a way to do this?

petko_stankoski
  • 10,459
  • 41
  • 127
  • 231
  • Why don't you prevent the exception being happen instead of letting it to happen and trying to restart it? Granted, some exceptions can't be prevented but there are only few. In those places you add exception handling. – Sriram Sakthivel Aug 21 '14 at 08:20
  • 3
    I believe nobody is so smart to write 100% error-prone code, so it is nice to handle the small percentage of unhandled exceptions in a user friendly way. – Vojtěch Dohnal Aug 21 '14 at 08:29
  • 2
    AppDomain.UnhandledExceptionHandler is there to give you a chance to log unhandled exceptions for debugging before exiting the program, not to avoid a crash. – chris Aug 21 '14 at 08:32
  • @chris I understand that. That's what I actually explained in the question. – petko_stankoski Aug 21 '14 at 08:44

4 Answers4

1

There is no way to do that and furthermore, it would unwise to attempt to do that. If an unhandled Exception has occurred, you have no idea what happened or why... to continue aimlessly after that point would not be a good idea because your app might have no internet or database connection, or any other problem that would render the application unusable.

A far better solution is to handle all of the situations where you think that an Exception is most likely to occur and then simply to document (or store in a database) any Exceptions that do occur and get caught in the AppDomain.UnhandledException handler.

Once an Exception has made its way to that handler, it's too late to avoid a shut down, but if you document the Exceptions that reach that point, then you can see what problems have been occurring and add further Exception handling to address those issues.

Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • 1
    _"to continue aimlessly after that point"_ though a fine general rule, the OP is not talking about letting the app continue, rather than let it reboot itself a finite number of times. It is a legitimate use case - think the **Recovery** tab in _Windows Services_ –  Aug 21 '14 at 10:20
0

Try:

    Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
    AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(AppDomain_UnhandledException);


    // Catch-all exception handler
    private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
    {
        if (e.Exception != null)
        {
           //do somethine
        }
        if (e.Exception.InnerException != null)
        {
            //do logging?
        }
        //do logging?
    }

    // Catch-all exception handler
    private static void AppDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        if (e.ExceptionObject != null)
        {
            if (e.ExceptionObject is Exception)
            {
                //do logging?
            }
        }

        //do logging?
    }
JKennedy
  • 18,150
  • 17
  • 114
  • 198
0

This works quite well for me:

  Application.Current.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(AppDispatcherUnhandledException);

  void AppDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
  {
        string message = e.Exception.Message;
        ...

To restart the WPF app I use Windows.Forms libraries:

System.Windows.Forms.Application.Restart();
Application.Current.Shutdown();
Vojtěch Dohnal
  • 7,867
  • 3
  • 43
  • 105
0

If you want your application to be restarted after a unhandled crash, for example if it is running on a Kiosk or something similar, you might want to wrap it in a simple shell.

This shell could start your applications, check the returnvalue when the application is ended, and restarts it when it appears to be crashed. You can count the amount of crashes and stop restarting the application after a number of times. Of course make use of AppDomain.UnhandledExceptionHandler to create a log of unhandled errors so you fix those and wrap the code in a try .. catch.

For example:

// Start the application and wait for it to exit.
var process = Process.Start(applicationPath, commandLineArguments);

process.WaitForExit();

// If the exit code is not 0, the application closed abnormally.
if (process.ExitCode != 0)
{
     // restart process   
}

If you use this technique than don't forget to disable error reporting so the restarting process will not be interrupted by a popup dialog

Community
  • 1
  • 1
Koen_R
  • 98
  • 9