C# – How to catch all unhandled exceptions in WinForms application correctly

cexceptionnetwinforms

I want to set the handler method for all unhandled exceptions from any threads in my WinForms application. I don't create any application domains by myself.

According to UnhandledException documentation, I need to set UnhandledExceptionMode.ThrowException mode via Application.SetUnhandledExceptionMode method to catch main thread's exceptions too:

In applications that use Windows Forms, unhandled exceptions in the
main application thread cause the Application.ThreadException event to
be raised. If this event is handled, the default behavior is that the
unhandled exception does not terminate the application, although the
application is left in an unknown state. In that case, the
UnhandledException event is not raised. This behavior can be changed
by using the application configuration file, or by using the
Application.SetUnhandledExceptionMode method to change the mode to
UnhandledExceptionMode.ThrowException before the ThreadException event
handler is hooked up. This applies only to the main application
thread. The UnhandledException event is raised for unhandled
exceptions thrown in other threads

So, the resulting code will look like the following:

    public static void UnhandledExceptionEventHandler(object sender, UnhandledExceptionEventArgs e)
    {
        // ...
    }

    [STAThread]
    static void Main(string[] args)
    {
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionEventHandler);

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MainForm(pathToCheck));
    }

Is it ok? Will it catch all unhandled exceptions from any threads (including the main thread, UI thread and all threads created by Task class)? Did I understand the documentation correctly?

Yes, I saw questions like this here, but I don't understand why should I also use the following code:

Application.ThreadException += new     
  ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);

Best Answer

You should subscribe both events. Note that even this will not catch automatically everything from other threads. For example, when delegates are invoked asynchronously, the exception will be propagated to the caller thread only when EndInvoke is called.

    [STAThread]
    static void Main(string[] args)
    {
        AppDomain.CurrentDomain.UnhandledException +=
            (sender, args) => HandleUnhandledException(args.ExceptionObject as Exception);
        Application.ThreadException +=
            (sender, args) => HandleUnhandledException(args.Exception);
    }

    static void HandleUnhandledException(Exception e)
    {
        // show report sender and close the app or whatever
    }