Unhandled Exception Handler in .NET 1.1

Oh, in Windows Forms you definitely should be able to get it to work. The only thing you have to watch out for is things happening on different threads.

I have an old Code Project article here which should help:

User Friendly Exception Handling


Unhandled exception behavior in a .NET 1.x Windows Forms application 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 Windows Forms exception handler
  • Whether you handled the CLR’s exception event
  • The phase of the moon

The default behavior 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, thread-pool, 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 handling does the following by default:

  • Catches an unhandled exception when:
    • exception is on main thread and no debugger attached.
    • exception occurs during window message processing.
    • jitDebugging = false in App.Config.
  • Shows dialog to user and prevents app termination.

You can disable the latter behavior 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.ThreadExceptionHandler(CatchFormsExceptions);

Note the registry setting DbgJitDebugLaunchSetting under HKEY_LOCAL_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 menu ToolsOptionsDebuggingJIT 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);