Mehdi LAMRANI
Mehdi LAMRANI

Reputation: 11607

Keep an Application Running even if an unhandled Exception occurs

What ?
I am developing a Console Application that needs to keep running 24/7 No Matter What
Is there any way to stop a Multi-Threaded Application from getting blown up by some unhandled exception happening in "some thread somewhere" ?

Why ?
Please refrain from giving lessons like "you should manage all your exceptions", "this should never happen" etc. I have my reasons : We are in test deployment and we need to keep this running, log exceptions, and restart all threads again. If anything unplanned happens and causes an unhandled exception to be thrown, it needs to be detected and some method called to restart all threads(atomicity is impossible due due the tier design)

This being said, I am aware it might no be possible to restart an application from "within" if it has blown because of and UnhandledException (which I already implemented).

So far, I have used Quartz.net's FileScan Job and a Flag File to detect stuff like that and restart the application from outwards. But this sounds hacky to me. I would like to find something cleaner and less quick and dirty.

DownVoting / Sniping Warning : I KNOW this might NOT be possible "as is'".
Please be creative/helpful rather than abruptly critic and think of this more as an "Open question"

Upvotes: 10

Views: 8282

Answers (5)

Jon Raynor
Jon Raynor

Reputation: 3892

If your using .Net 2.0 and above, the answer is you can't.

In the .NET Framework versions 1.0 and 1.1, an unhandled exception that occurs in a thread other than the main application thread is caught by the runtime and therefore does not cause the application to terminate. Thus, it is possible for the UnhandledException event to be raised without the application terminating. Starting with the .NET Framework version 2.0, this backstop for unhandled exceptions in child threads was removed, because the cumulative effect of such silent failures included performance degradation, corrupted data, and lockups, all of which were difficult to debug. For more information, including a list of cases in which the runtime does not terminate, see Exceptions in Managed Threads.

Taken from here:

http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx

If you want your application to survive, then you will need very aggressive try/catch around your methods so nothing escapes.

I would advise using a windows service as mentioned by others. It's the same as a console application, but with an extra bit of service layer code on top. You could take your console app and covert it to a service application easily. Just need to override service.start/pause/stop methods.

Upvotes: 2

JohnFx
JohnFx

Reputation: 34917

If it is going to run 24/7 anyway, why not just write it as a Windows service and take advantage of the recovery options built right into windows?

Configuring Recovery Services

This approach has the additional advantage of being able to survive a machine reboot, and it will log failures/restarts in the system event logs.

Upvotes: 12

Mehdi LAMRANI
Mehdi LAMRANI

Reputation: 11607

Well I can think of a few drawbacks in the following solution, but it is good enough to me for the moment :

static void Main()
    {
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(OnUnhandledException);
        CS = new ConsoleServer();
        CS.Run();            
    }

    public static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        Exception exception = (Exception)e.ExceptionObject;
        Logger.Log("UNHANDLED EXCEPTION : " + e.ExceptionObject.ToString());
        Process.Start(@"C:\xxxx\bin\x86\Release\MySelf.exe");
    }

Upvotes: 2

Ethan Cabiac
Ethan Cabiac

Reputation: 4993

You need to attach an event handler to UnhandledException event on the Current AppDomain:

AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler

Inside the handler, you will have to somehow save enough state (to a file, database, etc.) for the restarted application to pass along to the new threads. Then instantiate a new instance of your Console application with a call to System.Diagnostics.Process.Start("MyConsoleApp.exe").

Be very careful to introduce logic to avoid a continuous loop of crash/restart/crash/restart.

Upvotes: 9

John Saunders
John Saunders

Reputation: 161831

  • You can't keep a process running "no matter what". What if the process is killed?
  • You don't want to keep a process running "no matter what". What if the process state is corrupted in such a way that "bad things" happen if it keeps running?

Upvotes: 4

Related Questions