简体   繁体   中英

Catch all exception in C# winform application

in C# winform desktop application I'm trying to catch all exceptions possible to appear in the code, what I've tried:

  using System;
    using System.Threading;
    using System.Windows.Forms;

    namespace Controller
    {
        static class Program
        {
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);

                Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
                Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
                AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

                Application.Run(new Form1());
            }

            static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
            {
                MessageBox.Show(e.Exception.Message, "Unhandled Thread Exception");
            }

            static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
            {
                MessageBox.Show((e.ExceptionObject as Exception).Message, "Unhandled UI Exception");           
            }
        }
    }

I test it with attaching of "COM6" with form closing event without serial port in Device Manager, but I see only Visual Studio An exception of type 'System.InvalidOperationException' occurred in System.dll but was not handled in user code report

How it is possible to collect errors data for winform application

That's actually not that hard to do.
I would advise to put any code for handling the exception into the mainform to keep the program.cs as clean as possible.

First in your Program.cs put this

static class Program
{
    public static Form MainForm = null;

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        Application.ThreadException += Application_ThreadException;
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

        MainForm = new Form1();
        Application.Run(MainForm);
    }

    static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
    {
        ((Form1)MainForm).Application_ThreadException(sender, e);
    }
}

Then in your mainform put this

    public void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
    {
        // All unhandled exceptions will end up here, so do what you need here

        // log the error
        // show the error
        // shut the application down if needed
        // ROLLBACK database changes 
        // and so on...
    }

You can use try-catch to catch the exceptions in all methods. Inside catch you can log the reason for the exception.

try
{
   // Your code that might throw an error
}
catch( Exception e )
{
   // What you want to do when the error is thrown
   Logger.WriteException(e);
}

I would prefer writing a static class 'Logger' and 'WriteException' method for logging the exceptions to a text file.

public static class Logger
{
    public static void WriteException(Exception exception)
    {
        string filePath = @"D:\Error.txt";

        using (StreamWriter logWriter = new StreamWriter(filePath, true))
        {
            logWriter.WriteLine("Message :" + exception.Message + "<br/>" + Environment.NewLine + "StackTrace :" + exception.StackTrace +
               "" + Environment.NewLine + "Date :" + DateTime.Now.ToString());
            logWriter.WriteLine(Environment.NewLine + "-----------------------------------------------------------------------------" + Environment.NewLine);
        }
    }
}

There are several error logging methods available , you can use the suitable one for your application. You can use EventLog, Microsoft Logger etc.

catch all the errors in one single point in your application is not a best practice. I suggest you to identify where your code may fails and use try/catch block to catch specific groups of errors instead. In this way you can control more better your application and you can identify more better the weaknesses of your code. For example:

private void Form1_FormClosing(object sender, FormClosingEventArgs e) {

    try{
      //Put here your code
    }
    catch{
    }
}

A generic "Exception" for sure can't help you or the user to identify a possible error in the application

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