C# 3.0 Cookbook

Problem

You need to make absolutely sure that every exception thrown by your application is handled and that no exception is bubbled up past the outermost exception handler. Hackers often use these types of exceptions to aid in their analysis of the vulnerabilities of an application.

Solution

Place try-catch or try-catch-finally blocks in strategic places in your application. In addition, use the exception event handler as a final line of defense against unhandled exceptions.

Discussion

If an exception occurs and is not handled, it will cause your application to shut down prematurely. This can leave data in an unstable state, which may only be able to be rectified by manual interventionmeaning that you could be spending a long night cleaning up the data by hand. To minimize the damage, you can place exception handlers in strategic locations throughout your code.

The most obvious location to place exception handling code is inside of the Main method. The Main method is the entry point to executables (files with an .exe extension). Therefore, if any exceptions occur inside your executable, the CLR starts looking for an exception handler, starting at the location where the exception occurred. If none are found, the CLR walks the stack until one is found; each method on the stack is examined in turn to determine whether an exception handler exists. If no exception handlers are found in the final method in the stack, the exception is considered unhandled and the application is terminated . In an executable, this final method is the Main method.

In addition, or in place of using try-catch or try-catch-finally blocks at the entry point of your application, you can use the exception event handler to capture unhandled exceptions. Note that Windows Forms applications provide their own unhandled exception trap around exception handlers and never raise the AppDomain level event. There are two steps to setting up an exception event handler. The first is to create the actual event handler. This is done as follows :

static void LastChanceHandler(object sender, UnhandledExceptionEventArgs args) { try { Exception e = (Exception) args.ExceptionObject; Console.WriteLine("Unhandled exception == " + e.ToString( )); if (args.IsTerminating) { Console.WriteLine("The application is terminating"); } else { Console.WriteLine("The application is not terminating"); } } catch(Exception e) { Console.WriteLine("Unhandled exception in unhandled exception handler == " + e.ToString( )); } finally { // Add other exception logging or cleanup code here. } }

Next, you should add code to your application to wire up this event handler. The code to wire up the event handler should be executed as close to the start of the application as possible. For example, by placing this code in the Main method:

public static void Main( ) { AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(LastChanceHandler); //... }

you are assured of being able to clean up after any unhandled exception.

The exception event handler takes two parameters. The first is the sender object, which is the AppDomain object that threw the exception. The second argument is an UnhandledExceptionEventArgs object. This object contains all the relevant information on the unhandled exception. Using this object, we can obtain the actual exception object that was thrown as well as a Boolean flag that indicates whether the application will terminate.

Exception event handlers are a great help when used in multithreaded code. If an unhandled exception is thrown in a thread other than the main thread, that thread aborts. However, only the worker thread, and not the application as a whole, will terminate. But you are not clearly notified when the CLR aborts this thread, which can cause some interesting debugging problems. However, when an exception event handler is used, you can be notified of any unhandled exceptions that occur in any worker thread and that cause it to abort.

The exception event handler captures unhandled exceptions only for the primary application domain. Any application domains created from the primary application domain do not fire this event for unhandled exceptions.

See Also

See the "Error Raising and Handling Guidelines" and "UnhandledExceptionEventHandler Class" topics in the MSDN documentation.

Категории