如何在.NET应用程序中捕获所有异常/崩溃

时间:2020-03-05 18:58:42  来源:igfitidea点击:
Possible Duplicate:

  .NET - What’s the best way to implement a “catch all exceptions handler”

我有一个.NET控制台应用程序应用程序,它崩溃了并向用户显示一条消息。
我所有的代码都在一个try {<code>} catch(Exception e){<stuff>}`块中,但是仍然偶尔会显示错误。

在Win32应用程序中,我们可以通过安装各种异常处理程序来捕获所有可能的异常/崩溃:

/* C++ exc handlers */
_set_se_translator
SetUnhandledExceptionFilter
_set_purecall_handler
set_terminate
set_unexpected
_set_invalid_parameter_handler

.NET世界中等效的东西是什么,因此我可以处理/记录/安静所有可能的错误情况?

解决方案

回答

我们可以向AppDomain.UnhandledException事件添加事件处理程序,并且在引发异常且未捕获异常时将调用该事件处理程序。

回答

我们可以使用AppDomain.CurrentDomain.UnhandledException来获取事件。

回答

Global.asax类是最后一道防线。
看着:

protected void Application_Error(Object sender, EventArgs e)

方法

回答

我们也可以使用Application.ThreadException事件。

一旦我开发了在基于COM的应用程序中运行的.NET应用程序;此事件非常有用,因为AppDomain.CurrentDomain.UnhandledException在这种情况下不起作用。

回答

我认为我们甚至不应该捕获所有Exception,而最好让它们显示给用户。这样做的原因是我们应该只捕获可以实际处理的异常。如果我们遇到某种导致程序停止但仍然捕获的异常,则可能会导致更严重的问题。
另请参阅常见问题解答:为什么FxCop针对catch(Exception)发出警告?

回答

请注意,某些异常很容易被捕获或者难以捕获,

  • OutOfMemoryException:我们在catch处理程序中所做的任何事情都可能会分配内存(在CLR的托管或者非托管端),从而触发另一个OOM
  • StackOverflowException:根据CLR是否足够早地检测到它,我们可能会收到通知。最坏的情况是,它只是扼杀了进程。

回答

请注意,捕获这些未处理的异常可能会更改应用程序的安全要求。应用程序可能会在某些情况下(从网络共享等运行时)停止正确运行。确保彻底测试。

回答

我们所需要的是我们的主持人Jeff Atwood在codeproject中的这篇文章。
包括捕获未处理的异常和最佳实践的代码,以向用户显示有关崩溃的信息。

回答

尽管在没有计划正确处理它们的情况下捕获所有异常肯定是一个坏习惯,但我认为应用程序应该以某种正常的方式失败。崩溃应该不会吓死用户,至少它应该显示错误的描述,一些信息以向技术支持人员报告,并且最好是一个按钮来关闭应用程序并重新启动它。在理想情况下,应用程序应该能够将用户数据转储到磁盘上,然后尝试恢复它(但是我发现这要求太多)。

无论如何,我通常使用:

AppDomain.CurrentDomain.UnhandledException

回答

与其他人发布的内容相反,捕获所有异常没有错。重要的是要妥善处理它们。如果我们有堆栈溢出或者内存不足的情况,则应用程序应为它们关闭。另外,请记住,OOM条件可能会阻止异常处理程序正常运行。例如,如果异常处理程序显示带有异常消息的对话框,则如果内存不足,则对话框显示的空间可能不足。最好将其记录并立即关闭。

正如其他人提到的那样,我们可以处理UnhandledException和ThreadException事件,以处理否则可能会丢失的集合异常。然后只需在主循环中抛出一个异常处理程序(假设有一个winforms应用程序)。

另外,我们应该注意,并非总是由于内存不足情况而抛出OutOfMemoryExceptions。一个OOM条件可以触发代码中或者框架中的各种异常,这些异常与真正的基础条件已耗尽内存这一事实没有任何关系。当根本原因实际上是内存不足时,我经常会看到InvalidOperationException或者ArgumentException。

回答

两者都使用不会造成伤害
AppDomain.CurrentDomain.UnhandledException
Application.ThreadException

但是请记住,这些处理程序不会捕获辅助线程上的异常;如果需要,将SafeThread用于辅助线程