Unhandled Exceptions and Windows Forms
In a Windows Forms application, the System.Windows.Forms.Application class has a static Run method that's responsible for the thread's message loop. This loop dispatches window messages to a private method defined by the System.Windows.Forms.NativeWindow type. This method simply sets up a try/catch block and inside the try block, the protected WndProc method is called.
If a System.Exception-derived unhandled exception occurs while processing a window message, the catch block calls the window type's virtual OnThreadException method (passing it the exception object). System.Windows.Forms.Control type's implementation of OnThreadException ends up calling Application's OnThreadException. By default, this method displays a dialog box like the one shown in Figure 18-3.
Figure 18-3 : An unhandled exception in a window procedure causes Windows Forms to display this dialog box.
This dialog box appears when a window procedure has an unhandled CLS-compliant exception, notifying the user that an unhandled exception has occurred and giving the user the option of ignoring the window message and continuing to run or killing (quitting) the application. If the user ignores the exception, the application will continue running, but it has probably been corrupted and will behave unpredictably at this point. If the application processes a data file, the user should save the work to a new file.
Figure 18-3 : An unhandled exception in a window procedure causes Windows Forms to display this dialog box.
This dialog box appears when a window procedure has an unhandled CLS-compliant exception, notifying the user that an unhandled exception has occurred and giving the user the option of ignoring the window message and continuing to run or killing (quitting) the application. If the user ignores the exception, the application will continue running, but it has probably been corrupted and will behave unpredictably at this point. If the application processes a data file, the user should save the work to a new file.
Then the user should exit the application and restart it. Once restarted, the user should load the new file and check it to make sure it's not corrupted. If it is corrupted, then any new work would have been lost but the user can go back to the original file and make the changes again. If the new file seems OK, then the user can continue editing it and at some point delete the original file or keep it as a backup.
You can override the built-in dialog box by defining a method that matches the System.Threading.ThreadExceptionEventHandler delegate (defined in the System.dll assembly) and then registering your method with the Application type's static ThreadException event.
Note I think it's sad that this event didn't mimic the names and behavior of
AppDomain's UnhandledException event; that is, Application's event should have been called UnhandledException instead of ThreadException and it should have used the UnhandledExceptionEventHandler delegate instead.
You might have realized by now that Windows Forms deals only with CLS-compliant exceptions; non-CLS-compliant exceptions continue to propagate outside the thread's message loop and up the call stack. So if you want to display or log both CLS-compliant and non-CLS-compliant exceptions, you must define two callback methods and register one with the Application type's ThreadException event and register the other with AppDomain type's UnhandledException event.
As I explained, the behavior of NativeWindow's internal method is to catch all CLS-compliant exceptions and display a dialog box or call any callback method that you've registered with the ThreadException event. However, some situations can change this default behavior. First, if a debugger is attached to your Windows Forms application, any unhandled exception thrown from a window procedure isn't caught and the exception is allowed to propagate up the call stack. Second, if a JIT debugger is installed and if the jitDebugging configuration setting is specified in the application's XML .config file, then again, the exception isn't caught and the exception is allowed to propagate up the call stack.
Average user rating: 5 stars out of 1 votes
Post a comment