How can I detect that my .NET application has crashed, and then restart it?
A:
A possible solution is to create another process to monitor your application, and restart it if it is terminated:
class ProcessMonitorProgram
{
const string myProcess = "MyApp.exe";
static void Main()
{
new Timer(CheckProcess, null, 0, 60 * 1000);
Thread.Sleep(Timeout.Infinite);
}
static void CheckProcess(object obj)
{
if (Process.GetProcessesByName(myProcess).Length == 0)
Process.Start(myProcess);
}
}
One of the problems with this solution is that it will keep the process restarting forever, until this monitoring application itself is terminated.
Hosam Aly
2009-02-08 14:43:25
+5
A:
Another solution (based on this example) is to create a launcher that controls the application:
class LauncherProgram
{
static int count = 3;
static void Main()
{
Launch();
Thread.Sleep(Timeout.Infinite);
}
static void Launch()
{
Process process = new Process();
process.StartInfo.FileName = "MyApp.exe";
process.EnableRaisingEvents = true;
process.Exited += LaunchIfCrashed;
}
static void LaunchIfCrashed(object o, EventArgs e)
{
Process process = (Process) o;
if (process.ExitCode != 0)
{
if (count-- > 0) // restart at max count times
Launch();
else
Environment.Exit(process.ExitCode);
}
else
{
Environment.Exit(0);
}
}
Hosam Aly
2009-02-08 14:44:09
The only possible upgrade would be to make the "watchdog" a windows service.
Ryan Emerle
2009-02-08 15:02:10
+5
A:
- run the work inside an AppDomain; use the primary AppDomain to monitor it (doesn't guard against process kill, though)
- lots of exception handling! i.e. don't let a fatal error tear down the process
- run it in something that already has recycling built in - IIS for example
Marc Gravell
2009-02-08 14:44:44
Thanks Marc. Could you please add an example on how to implement the AppDomain-based solution you suggest?
Hosam Aly
2009-02-08 14:46:55
Assuming this is a Windows Forms or console app, you can use Application.Restart - see my answer for details.
RoadWarrior
2009-02-08 23:37:33
+3
A:
If this is a Windows Forms app:
- Set jitDebugging = true in App.Config. This prevents the built-in Windows Forms unhandled exception handler being triggered.
Now regardless of whether this is a Windows Forms app or a console app:
Register for the Application.ThreadException event, e.g. in C#:
Application.ThreadException += new Threading.ThreadExceptionHandler(CatchFatalException);
At this point, your app is already on its way into a black hole. What happens next depends on whether or not this is a Windows Forms app:
- If it's a Windows Forms app, call the Application.Restart method in your CatchFatalException event handler.
- Otherwise you will instead need to p/invoke to the application restart and recovery native functions. That link discusses Vista, but in my tests it works just fine on XP as well.
RoadWarrior
2009-02-08 17:18:05
Thank you. Is it possible for a console application to do something similar to `Application.ThreadException += MyHandler;`?
Hosam Aly
2009-02-08 21:51:58
It does have access to the Application class if you add the correct namespace. But in my test, I see an "Unsupported" exception, so you're right, this doesn't work for Console apps. I will change my answer to reflect this.
RoadWarrior
2009-02-09 09:17:04