.NET - What's the best way to implement a "catch all exceptions handler"

I have just played with AppDomain's UnhandledException behavior, (this is the last stage the unhandled exception is registered at)

Yes, after processing the event handlers your application will be terminated and the nasty "... program stopped working dialog" shown.

:) You still can avoid that.

Check out:

class Program
{
    void Run()
    {
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

        Console.WriteLine("Press enter to exit.");

        do
        {
            (new Thread(delegate()
            {
                throw new ArgumentException("ha-ha");
            })).Start();

        } while (Console.ReadLine().Trim().ToLowerInvariant() == "x");


        Console.WriteLine("last good-bye");
    }

    int r = 0;

    void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        Interlocked.Increment(ref r);
        Console.WriteLine("handled. {0}", r);
        Console.WriteLine("Terminating " + e.IsTerminating.ToString());

        Thread.CurrentThread.IsBackground = true;
        Thread.CurrentThread.Name = "Dead thread";            

        while (true)
            Thread.Sleep(TimeSpan.FromHours(1));
        //Process.GetCurrentProcess().Kill();
    }

    static void Main(string[] args)
    {
        Console.WriteLine("...");
        (new Program()).Run();
    }
}

P.S. Do handle the unhandled for Application.ThreadException (WinForms) or DispatcherUnhandledException (WPF) at the higher level.


In ASP.NET, you use the Application_Error function in the Global.asax file.

In WinForms, you use the MyApplication_UnhandledException in the ApplicationEvents file

Both of these functions are called if an unhandled exception occurs in your code. You can log the exception and present a nice message to the user from these functions.


For Winform applications, in addition to AppDomain.CurrentDomain.UnhandledException I also use Application.ThreadException and Application.SetUnhandledExceptionMode (w/ UnhandledExceptionMode.CatchException). This combination seems to catch everything.


On the main thread, you have the following options:

  • Console or Service application: AppDomain.CurrentDomain.UnhandledException
  • WinForms application: Application.ThreadException
  • Web application: Global.asax's Application_Error

For other threads:

  • Secondary threads have no unhandled-exceptions; use SafeThread
  • Worker threads: (timer, threadpool) there is no safety net at all!

Bear in mind that these events do not handle exceptions, they merely report them to the application--often when it is far too late to do anything useful/sane about them

Logging exceptions is good, but monitoring applications is better ;-)

Caveat: I am the author of the SafeThread article.