收集崩溃数据的最佳方法是什么?

时间:2008-12-14 16:51:21

标签: c# exception exception-handling

所以我出售了试图从程序中自动收集数据的概念 - 即弹出一个对话框,要求用户在出现问题时发送报告。

我在MS Visual Studio C#中工作。

从实现的角度来看,在我的主program.cs文件中放置一个try / catch循环是否有意义?像这样:

        try
        {
            Application.Run(new myMainForm());
        }
        catch (Exception ex)
        {
            //the code to build the report I want to send and to 
            //pop up the Problem Report form and ask the user to send

        }

或者在整个代码段中放置try / catch循环以捕获更具体的异常类型是否有意义? (我想的不是因为这是一个新的应用程序,并且提出更具体的异常捕获意味着我知道会出现什么问题......我不知道,这就是为什么以上对我来说似乎有意义。)

-Adeena

6 个答案:

答案 0 :(得分:9)

我认为你是对的,你不会知道会出现什么问题,这就是重点。

但是,您可以考虑在ThreadException事件中添加处理程序。

上面的代码可以使用,但是有些情况下多线程可能是这些代码的问题,因为并非所有Windows窗体程序中的代码都将在主Application.Run循环线程中运行。

以下是链接文章的示例代码:

[STAThread]
static void Main() 
{
   System.Windows.Forms.Application.ThreadException += new ThreadExceptionEventHandler(ReportError);
   System.Windows.Forms.Application.Run(new MainForm());
}

private static void ReportError(object sender, ThreadExceptionEventArgs e)
{
   using (ReportErrorDialog errorDlg = new ReportErrorDialog(e.Exception))
   {
    errorDlg.ShowDialog();
   }
}

更多文档on MSDN

在一个小问题上,使用ThreadException事件还允许主消息循环继续运行,以防异常不是致命的(即容错方案),而try / catch方法可能需要您重新启动主消息循环可能会导致副作用。

答案 1 :(得分:1)

  

从实现的角度来看,在我的主program.cs文件中放置一个try / catch循环是否有意义,在运行应用程序的地方?

当然,永远。

你应该在任何关键的地方使用Try / Catch-Blocks,这可能引发异常。

因此,你不能真正坚持一种模式,因为你现在应该提出什么样的例外。否则这些都是未处理的异常,这会让您的程序崩溃。

但是有很多例外,它们不需要完全停止应用程序,例外,它们可以被吞噬,因为它们是预期的,并且不需要应用程序停止。使用您的程序移动或访问数据时,示例是UnauthorizedAccessExceptions。

由于性能的原因,您应该尽量让Try / Catch-Blocks尽可能小,并且不要使用太少的。/ / p>

有些人使用Try / Catch来指导程序的执行。在任何可能的情况下应该完全避免这种情况,因为引发异常是性能杀手1号。

答案 2 :(得分:1)

在整个应用程序中包含try catch将意味着应用程序将在出错时退出。

虽然使用try和catch各种方法很难维护。

最佳做法是围绕将抛出特定异常类型(如FormatException)的代码单元使用特定的try catch,并将常规异常处理留给应用程序级事件处理程序。

try
        {
            //Code that could error here
        }
        catch (FormatException ex)
        {
            //Code to tell user of their error
            //all other errors will be handled 
            //by the global error handler
        }

经验会告诉你可能出错的事情类型。随着时间的推移,您会注意到您的应用经常在文件访问时抛出IO异常,以便稍后可以捕获这些并为用户提供更多信息。

错误的全局处理程序将捕获其他所有内容。您可以通过将事件处理程序连接到两个事件System.Windows.Forms.Application.ThreadException(see MSDN)和AppDomain.UnhandledException(see MSDN

来使用它们。

请注意,任何错误捕获都可能无法捕获Out of Memory异常和StackOverflowException。

答案 3 :(得分:1)

如果您确实希望自动获取堆栈跟踪,Microsoft允许您通过错误报告服务提交它们。您需要做的就是从VeriSign注册数字证书并向Microsoft注册(免费)。

Microsoft随后会为您提供登录信息,以便您从网站下载小型转储,这些转储是在用户单击“发送错误报告”时提交的。

虽然人们可以点击“不发送”,但至少它是一个Microsoft对话框,可能不是你必须自己编码的对话框。它将全天候运行,您不必担心Web服务器的正常运行时间,您可以为用户提交解决方法详细信息,并且可以通过Windows Update提供更新。

有关此服务的信息位于此“Windows Error Reporting: Getting Started”文章中。

答案 4 :(得分:0)

最好的方法是唱歌 AppDomain.UnhandledExceptionApplication.ThreadException在您的应用程序的主要功能中。这将允许您在应用程序中记录任何未处理的异常。在try catch块中运行并不能完成所有事情。

答案 5 :(得分:0)

如果您只想捕获崩溃,请忽略所有错误,让DrWatson为您生成一个小型转储。然后你可以在调试器中查看(windbg是minidumps的首选),它会向你显示代码出错的行,以及所有参数,堆栈跟踪和寄存器。您可以将Drwatson设置为生成完整转储,您将获得整个内存核心转储以进行调查。

我不建议在整个应用程序周围放置一个try / catch,除非你希望你的应用程序永远不会在用户面前“崩溃” - 它将永远被处理,并且可能被忽略,因为你无能为力那个例外。

向你发送minidump是另一回事,here's an article,你必须做一些工作才能通过email / http / ftp / etc发送它。