在C# Winform应用程序中捕获所有异常

6
在C# Winform桌面应用程序中,我正在尝试捕获所有可能出现的异常,我尝试过的方法是:
  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");           
            }
        }
    }

我在关闭表单事件时附加“COM6”进行测试,但在设备管理器中未找到串口,只看到Visual Studio An exception of type 'System.InvalidOperationException' occurred in System.dll but was not handled in user code 报告。

如何收集WinForm应用程序的错误数据?


一旦遇到未处理的运行时错误,执行就会停止。除非您报告错误并允许其继续,否则您将看不到任何其他错误,因为应用程序已停止运行。 - itsme86
3个回答

7

这其实并不难做到。


我建议将处理异常的代码放入主窗体中,以使program.cs尽可能干净。

首先在您的Program.cs中添加以下内容:

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

然后在您的主表单中加入以下内容。
    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...
    }

你好,我已经尝试过这个方法,但是仍然出现了同样的问题。我只看到了Visual Studio报告的异常情况,例如An exception of type 'System.InvalidOperationException' occurred in System.dll but was not handled in user code,并且在Form1.cspublic Form1()下面添加了Application_ThreadException和相同的串口测试以及MessageBox.Show - user10388599
2
这只会捕获未处理的异常。有可能库会捕获异常并使用 messagebox.show 显示此信息。在这种情况下,您将无法捕获它,因为它已经在其他地方被捕获了。 - GuidoG
到处寻找解决方案,这个方法非常有效! - Troy Mac1ure

1
你可以使用try-catch来捕获所有方法中的异常。在catch中,你可以记录异常的原因。
try
{
   // Your code that might throw an error
}
catch( Exception e )
{
   // What you want to do when the error is thrown
   Logger.WriteException(e);
}

我希望编写一个静态类“Logger”,并编写“WriteException”方法,将异常记录到文本文件中。
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);
        }
    }
}

有多种错误日志记录方法可供选择,您可以根据应用程序使用适合的方法。您可以使用EventLog、Microsoft Logger等。


你好,是的,我正在为每个特定的异常情况存储数据,但我想知道是否可能获得单个事件,并提供任何其他可能的情况的常见报告,无论是否由已经存在于单独函数中的每个个体异常条件提供。 - user10388599

-1
在您的应用程序中捕获所有错误并不是最佳实践。我建议您确定代码可能出错的位置,并使用try/catch块来捕获特定组的错误。这样,您可以更好地控制应用程序,并更好地识别代码的弱点。例如:
private void Form1_FormClosing(object sender, FormClosingEventArgs e) {

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

一个普通的“异常”肯定不能帮助您或用户识别应用程序中可能出现的错误。

你好,是的,我使用异常捕获来处理所有可能的情况,但如果可以获取所有情况的通用报告,那么消息内容应该是什么,如何处理这个事件? - user10388599

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接