程序从不尝试从哪个例外中恢复?

时间:2012-03-13 18:25:41

标签: c# .net vb.net

例外可能会对程序产生不同程度的影响。例如,如果引发OutOfMemoryException,程序应该可以中止,但是可以安全,适当地处理System.Data.SqlClient.SqlException而不将程序置于未知状态。

我确实理解,如果没有正确处理,任何异常都有可能使程序处于不稳定状态。是否存在除了简单地记录和抛弃堆栈之外永远不应该处理的异常?

6 个答案:

答案 0 :(得分:36)

这是一个逐案理论问题,因此答案将与理论一样。我听过的最好的答案是,“如果您不知道 如何处理它,请不要处理异常。”记录消息并抛出异常向上堆栈很好,因为你实际上完成某事(即使它只是表明发生了错误)。但是,捕获错误并且将其抛出堆栈可能会导致隐藏的错误和困难的调试会话。

我们一直在做的是实现一个顶级错误处理程序,它将执行一般错误处理(比如记录消息,提醒开发人员等)。所有在代码中未处理的异常至少由顶级处理程序处理。 可以在代码中处理得更低的例外肯定会在它们发生的地方处理。

考虑循环电子邮件地址列表以将邮件发送到邮件列表的情况。如果其中一个电子邮件地址格式不正确,但我们不希望单个电子邮件地址导致其余处理失败,则可能会发生异常。通过处理发生的特定异常类型,我们可以记录它(甚至将电子邮件地址标记为无效)并继续处理列表的其余部分。

底线:您是否处理给定的异常类型实际上取决于您的代码是否知道在发生异常类型时如何恢复。

答案 1 :(得分:18)

Framework Design Guidelines cover this pretty completely

  

不要在框架中捕获System.Exception或System.SystemException   代码,除非你打算重新抛出。

     

...

     

不要捕获System.StackOverflowException。

     

以编程方式处理堆栈溢出非常困难。   您应该允许此异常终止进程并使用   调试以确定问题的根源。

     

...

     

不要显式捕获System.Runtime.InteropServices.SEHException。

答案 2 :(得分:4)

这可能是一个不同的场景,但是任何意味着程序员错误的异常:NullReferenceExceptionIndexOutOfRangeException等等。这意味着您的代码中存在错误,您应该修复它而不是处理它它

答案 3 :(得分:3)

这高度依赖于您的应用程序。大多数应用程序应该显示错误消息并且为OutOfMemoryException而死,但不是全部 - 例如,一个名为SmartRAM的程序(我认为这是名称)通过尝试分配越来越多的内存来恢复RAM,直到它获得异常 - 这会导致Windows丢弃RAM中的所有缓存,为您提供更多可用内存。

所以这真的取决于你在做什么。如果您作为应用程序的专家,感觉您可以安全地从异常中恢复,那么您应该。

答案 4 :(得分:1)

典型的异常层次结构有两个主要分支,运行时逻辑错误。前者可以随时出现,而且程序很少有关于如何恢复的明智的想法,后者是一个需要预测和处理的错误条件。

Java使用checked exceptions的实现明确区分了这一区别。如果没有处理任何异常或将其声明为方法的潜在异常退出,则会出现错误,但RuntimeException的任何后果都是隐含的。

如果你的程序被适当地划分为,则用例允许它,你可以捕获某些运行时异常并关闭发生异常的隔离区,但这仅在特殊情况下有用。 / p>

虽然这只是在Java中主动实施,但这里也可以应用这个概念:

  • 无法解析输入数据是一个可以轻松处理的异常,因为很清楚抛出异常时程序处于哪种状态,因此清理很容易(继续下一次输入)。
  • 从内存不足情况中恢复更难,因为如果在写入时发生错误,您可能需要删除输出文件 - 否则您最终会得到部分数据。
  • 如果你的程序访问了无效的内存,你不应该尝试恢复,因为你可能已经覆盖了其他东西(毕竟,你的程序显然不知道它的数据在哪里),并且没有办法保证它会正常工作。

答案 5 :(得分:0)

这取决于程序中异常发生的位置。

一般情况下,最好处理您的各个代码段想要/知道如何处理的异常,并让其余部分在其他地方处理,或者根本不处理。