Crash Recovery in Application
Asked Answered
V

3

6

What's the best way (standard solution maybe) to build crash recovery into my application so it can automatically restart on any kind of crash.

tnx.

Vociferate answered 14/3, 2011 at 18:12 Comment(3)
Do you have any state in your application?Opec
State, like current view, unsaved changes, navigation history, everything about what and where the application "is" and what the user has created.Opec
@Albin: pretty much every application built falls under that definition..Accustom
A
6

You have a few options here.

The first (and best) one is to add some type of global error handling which will catch any otherwise uncaught exceptions and properly deal with them. Along these lines you should start adding the appropriate specific exception handling to your code base. Bear in mind that stack overflow and certain security and memory exceptions will blow past any global handling regardless.

A second option is to have a monitoring service which just tests to see if the current app is still working. If it isn't then force kill the existing app and restart a new instance.

A third option is to separate your application into two apps. An outer "container" type app that simply executes the other process. The container app won't have a UI, but will start the main process and watch it (much like option 2 above). I've seen this one used in various "modular" applications.

The point is, the only real way to do this is to have 2 apps: one to monitor, the other to actually do the UI and everything else.

Accustom answered 14/3, 2011 at 18:15 Comment(1)
A global error 'handler' cannot handle many errors, as it rarely has enough context to know whether it's safe to continue (i.e. whether the application state is still valid.) In order to deal with true crashes (exceptions that could not be or were not handled at an appropriate layer), I vote for the hosting process solution, which starts and stops with the main process. In .NET, this can often be accomplished cleanly by using a separate AppDomain for the hosted application, rather than requiring an entirely separate process.Rosalindarosalinde
D
10

It is in general better not to do this, there's nothing pretty about a process that constantly starts and immediately crashes again with the user helplessly looking at the carnage. But I can only hand you the bullets, aiming the gun at your foot is up to you. You'll need code like this:

    static void Main(string[] args) {
        AppDomain.CurrentDomain.UnhandledException += ReportAndRestart;
        // etc..
    }

    static void ReportAndRestart(object sender, UnhandledExceptionEventArgs e) {
        string info = e.ExceptionObject.ToString();
        // Log or display info 
        //...
        // Let the user know you're restarting
        //...
        // And restart:
        System.Diagnostics.Process.Start(
            System.Reflection.Assembly.GetEntryAssembly().Location,
            string.Join(" ", Environment.GetCommandLineArgs()));
        Environment.Exit(1);
    }
}

Beware that I took a shortcut on the command line arguments. They should be quoted if they contain a path to a file that contains spaces. Don't take shortcuts on the code you're supposed to put in the ellipsis.

Dailey answered 14/3, 2011 at 18:44 Comment(2)
One solution to the constantly restarting crashing process that Windows Services uses is a limit on the number of times it will attempt to restart the process. This works best when you have an outer 'hosting' process that monitors the launched application and can therefore maintain state about its crashes. This works better for services than a UI-based application, however, as at least with services, the crashing and restarting is mostly transparent to the user.Rosalindarosalinde
How about recovering the state of application? Each unit could have state that is crucial to the continuation of the application.Bragg
A
6

You have a few options here.

The first (and best) one is to add some type of global error handling which will catch any otherwise uncaught exceptions and properly deal with them. Along these lines you should start adding the appropriate specific exception handling to your code base. Bear in mind that stack overflow and certain security and memory exceptions will blow past any global handling regardless.

A second option is to have a monitoring service which just tests to see if the current app is still working. If it isn't then force kill the existing app and restart a new instance.

A third option is to separate your application into two apps. An outer "container" type app that simply executes the other process. The container app won't have a UI, but will start the main process and watch it (much like option 2 above). I've seen this one used in various "modular" applications.

The point is, the only real way to do this is to have 2 apps: one to monitor, the other to actually do the UI and everything else.

Accustom answered 14/3, 2011 at 18:15 Comment(1)
A global error 'handler' cannot handle many errors, as it rarely has enough context to know whether it's safe to continue (i.e. whether the application state is still valid.) In order to deal with true crashes (exceptions that could not be or were not handled at an appropriate layer), I vote for the hosting process solution, which starts and stops with the main process. In .NET, this can often be accomplished cleanly by using a separate AppDomain for the hosted application, rather than requiring an entirely separate process.Rosalindarosalinde
F
0

Put your persistent state in something that supports transactions. Eg. Database (sqlite) or if the needs are not too complex, use copy on write (write changes to a new file, and only if that was successful discard the old file)

These suggestions are very generic.

Fabricate answered 14/3, 2011 at 18:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.