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

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

我在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循环以捕获更具体的exception类型是否有意义? (我想的不是因为这是一个新的应用程序,并且提出更具体的exception捕获意味着我知道会出现什么问题……我不知道,这就是为什么以上对我来说似乎有意义。)

-Adeena

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

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

上面的代码可以工作,但是有些情况下multithreading可能是这些代码的问题,因为并非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(); } } 

有关MSDN的更多文档。

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

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

当然,永远。

你应该使用Try / Catch-Blocks,无论你做什么都是关键的,这可能会引发exception。

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

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

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

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

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

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

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

 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 } 

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

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

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

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

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

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

有关此服务的信息位于此“ Windows错误报告:入门 ”一文中。

最好的方法是为你的应用程序的主函数提供AppDomain.UnhandledException和Application.ThreadException 。 这将允许您在应用程序中记录任何未处理的exception。 在try catch块中运行并不会捕获所有内容。

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

我不建议在整个应用程序周围放置一个try / catch,除非你希望你的应用程序永远不会在用户面前“崩溃” – 它将永远被处理,并且可能被忽略,因为你无法做任何关于exception的事情。那一点。

将minidump发送给你是另一回事, 这是一篇文章 ,你必须做一些工作才能通过email / http / ftp / etc发送它。