可能的重复:
.NET - 实现“捕获所有异常处理程序”的最佳方法是什么

我有一个 .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 世界中的等效项是什么,以便我可以处理/记录/消除所有可能的错误情况?

有帮助吗?

解决方案

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

正如其他人提到的,您可以处理 UnhandledException 和 ThreadException 事件来处理可能会错过的集合异常。然后只需在主循环周围抛出一个异常处理程序(假设是一个 winforms 应用程序)。

另外,您应该注意,内存不足的情况并不总是会引发 OutOfMemoryException。OOM 条件可能会在代码或框架中触发各种异常,这些异常不一定与真正的底层条件内存不足这一事实有关。当根本原因实际上是内存不足时,我经常看到 InvalidOperationException 或 ArgumentException。

其他提示

您可以向 AppDomain.UnhandledException 事件添加一个事件处理程序,当抛出异常但未捕获异常时,它将被调用。

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

全局.asax 班级是你的最后一道防线。看着:

protected void Application_Error(Object sender, EventArgs e)

方法

请注意,某些异常捕获起来很危险 - 或者大多数情况下无法捕获,

  • 内存不足异常:在 catch 处理程序中执行的任何操作都可能会分配内存(在 CLR 的托管或非托管端),从而触发另一个 OOM
  • 堆栈溢出异常:根据 CLR 是否足够早地检测到它,您可能会收到通知。最坏的情况是,它只会杀死进程。

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

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

无论如何,我通常使用:

AppDomain.CurrentDomain.UnhandledException

您也可以使用 Application.ThreadException 事件。

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

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

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

使用两个AppDomain.CurrentDomain.unhandledException应用程序。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top