简体   繁体   中英

How to catch all unhandled exceptions in WinForms application correctly

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);

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
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM