To catch all exceptions from a thread, you surround the initial thread start method with a try/catch/finally block, just as you would for all code within Main(). However, what happens if a third-party component creates an alternate thread and throws an unhandled exception from that thread? A try/catch block in Main() will not catch an exception in an alternate thread. Even if it did, the code could never appropriately recover from all possible exceptions and continue executing. The general unhandled-exceptions guideline is for the program to shut down and restart in a clean state, instead of behaving erratically or hanging because of an invalid state.
Instead of crashing suddenly or ignoring the exception entirely if it occurs on an alternate thread, it is often desirable to save any working data and/or log the exception for error reporting and future debugging. This requires a mechanism to register for notifications of unhandled exceptions.
Registering for unhandled exceptions on the main application domain occurs via an application domain's UnhandledException event. Listing 15.6 demonstrates that process, and Output 15.5 shows the results.
Listing 15.6. Registering for Unhandled Exceptions
The UnhandledException callback will fire for all unhandled exceptions on threads within the application domain, including the main thread. This is a notification mechanism, not a mechanism to catch and process exceptions so that the application can continue. After the event, the application should be programmed to exit.