Recipe7.20.Dealing with Unhandled Exceptions in WinForms Applications


Recipe 7.20. Dealing with Unhandled Exceptions in WinForms Applications

Problem

You have a WinForms-based application in which you want to catch and log any unhandled exceptions on any thread.

Solution

You need to hook up handlers for both the System.Windows.Forms.Application. ThreadException event and the System.appdomain.UnhandledException event. Both of these events need to be hooked up, as the WinForms support in the Framework does a lot of exception trapping itself. It exposes the System.Windows.Forms.Application.ThreadException event to allow you to get any unhandled exceptions that happen on the UI thread that the WinForms and their events are running on. In spite of its deceptive name, the System.Windows.Forms.Application.ThreadException event handler will not catch unhandled exceptions on worker threads constructed by the program or from ThreadPool threads. In order to catch all of those possible routes for unhandled exceptions in a WinForms application, you need to hook up a handler for the System.appdomain.UnhandledException event that does catch those (but not the UI thread ones that System.Windows.Forms.Application.ThreadException does).

To hook up the necessary event handlers to catch all of your unhandled exceptions in a WinForms application, add the following code to the Main function in your application:

 static void Main() {     // Adds the event handler to catch any exceptions that happen     // in the main UI thread.     Application.ThreadException +=         new ThreadExceptionEventHandler(OnThreadException);     // Add the event handler for all threads in the appdomain except     // for the main UI thread.     appdomain.CurrentDomain.UnhandledException +=         new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);     Application.EnableVisualStyles();     Application.Run(new Form1()); } 

The System.appdomain.UnhandledException event handler is hooked up to the current appdomain by using the appdomain.CurrentDomain property, which gives access to the current appdomain. The ThreadException handler for the application is accessed through the Application.ThreadException property.

The event handler code is established in the CurrentDomain_UnhandledException and OnThreadException handler methods. See Recipe 7.10 for more information on the UnhandledExceptionEventHandler. The ThreadExceptionEventHandler is passed the sender object and a ThreadExceptionEventArgs object. THReadExceptionEventArgs has an Exception property that contains the unhandled exception from the WinForms UI thread.

 // Handles the exception event for all other threads static void CurrentDomain_UnhandledException(object sender,                             UnhandledExceptionEventArgs e) {     // Just show the exception details.     MessageBox.Show("CurrentDomain_UnhandledException: " +                 e.ExceptionObject.ToString()); } // Handles the exception event from a UI thread static void OnThreadException(object sender, ThreadExceptionEventArgs t) {     // Just show the exception details.     MessageBox.Show("OnThreadException: " + t.Exception.ToString()); } 

Discussion

Exceptions are the primary way to convey errors in .NET, so when you build an application it is imperative that there be a final line of defense against unhandled exceptions. An unhandled exception will crash the program (even if it looks a bit nicer in .NET); this is not the impression you wish to make on your customers. It would have been nice to have one event to hook up to for all unhandled exceptions. The appdomain.UnhandledException event comes pretty close to that, but having to do handle one extra event isn't the end of the world either. In coding event handlers for both appdomain.UnhandledException and Application.ThreadException, you can easily call a single handler that writes the exception information to the event log, the debug stream, or custom trace logs or even sends you an email with the information. The possibilities are limited only by how you want to handle errors that can happen to any program given enough exposure.

See Also

See Recipe 7.10; see the "Error Raising and Handling Guidelines," "Thread-ExceptionEventHandler Delegate," and "UnhandledExceptionEventHandler Delegate" topics in the MSDN documentation.



C# Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2004
Pages: 424

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net