Unhandled exception behavior in a .NET 1.x WinForms app depends on:
- The type of thread that threw the exception
- Whether it occurred during window message processing
- Whether a debugger was attached to the process
- The DbgJitDebugLaunchSetting registry setting
- The jitDebugging flag in App.Config
- Whether you overrode the WinForms exception handler
- Whether you handled the CLR’s exception event
- The phase of the moon
The default behaviour of unhandled exceptions is:
- If the exception occurs on the main thread when pumping window messages, it's intercepted by the Windows Forms exception handler.
- If the exception occurs on the main thread when pumping window messages, it will terminate the app process unless it's intercepted by the Windows Forms exception handler.
- If the exception occurs on a manual, threadpool, or finalizer thread, it's swallowed by the CLR.
The points of contact for an unhandled exception are:
- Windows Forms exception handler.
- The JIT-debug registry switch DbgJitDebugLaunchSetting.
- The CLR unhandled exception event.
The Windows Form built-in exception does the following by default:
- Catches an unhandled when:
- exception is on main thread and no debugger atached.
- exception occurs during window message processing.
- jitDebugging = false in App.Config.
- Shows dialog to user and prevents app termination.
You can disable the latter behaviour by setting jitDebugging = true in App.Config. But remember that this may be your last chance to stop app termination. So the next step to catch an unhandled exception is registering for event Application.ThreadException, e.g. :
Application.ThreadException += new Threading.ThreadExceptiopnHandler(CatchFormsExceptions);
Note the registry setting DbgJitDebugLaunchSetting under HKEY_LOCVAL_MACHINE\Software.NetFramework. This has one of three values of which I'm aware:
- 0: shows user dialog asking "debug or terminate".
- 1: lets exception through for CLR to deal with.
- 2: launches debugger specified in DbgManagedDebugger registry key.
In Visual Studio, go to Tools>Options>Debugging>JIT to set this key to 0 or 2. But a value of 1 is usually best on an end-user's machine. Note that this registry key is acted on before the CLR unhandled exception event.
This last event is your last chance to log an unhandled exception. It's triggered before your Finally blocks have executed. You can intercept this event as follows:
AppDomain.CurrentDomain.UnhandledException += new System.UnhandledExceptionEventHandler(CatchClrExceptions);