As a rule, in every application I write, I always implement both the Application.ThreadException and AppDomain.UnhandledException events, to catch exceptions which were not caught by a try..catch block.
There are three reasons behind this:
- Present a custom failure message to the user (something like Twitter’s fail whale message) instead of the default ugly (and unclear) error dialog, i.e. “XXX.exe has encountered a problem and needs to close. We are sorry for the inconvenience.“
- Log the exception so it may be resolved in future releases.
- Although it’s not considered as a good practice, some exception may be ignored so the application may keep on running, instead of crashing.
However, I recently came across a case in which the application crashed ungracefully although I implemented those methods. Some research led to me to realize my code is not as full-proof as I thought it was.
The code below will crash your application even if you hooked the two events mentioned above. The UnhandledException event WILL be executed, but afterwards the application will crash anyway, presenting Microsoft’s default error dialog:
private void MyThreadProc()
throw new Exception(”Bad wolf”);
private void ClickMe()
Thread myThread = new Thread(new ThreadStart(MyThreadProc));
Turns out I was not aware that during the transition between Framework 1.1 and 2.0 (and beyond), Microsoft changed the way the CLR deals with exception that don’t occurs in the application’s main thread, meaning that if you want the application to remain alive even after an external thread exception, you need to tell the CLR to revert to the Framework 1.1 exception handling mechanism, by adding this section to your app.config file:
<legacyUnhandledExceptionPolicy enabled=”1″ />
Again, not a best practice, but if you can’t afford to having
Another footnote is related to using the Application.SetUnhandledExceptionModeMethod. If you try setting it from a Winform application running inside the Visual Studio, you’ll get the following error: “Application exception mode cannot be changed once any Controls are created in the application“, even if that’s the first line of code in the application. This is because the Visual Studio runs a host environment prior to running your application. The methods works just fine when you run it from outside the Visual Studio.