题
我是否应该始终将外部资源调用包装在 try-catch 中?(IE。调用数据库或文件系统)调用外部资源时是否有错误处理的最佳实践?
解决方案
抓住可以处理的唯一例外 。因此,例如在使用外部资源时,最佳做法是捕获您知道可以处理的特定异常。如果是文件,则可以是(IOException,SecurityException等),对于Database,异常可以是SqlException或其他。
在任何情况下,不会抓住不处理的例外,让它们流向可以的上层。或者,如果由于某种原因你捕获异常但不处理它们,只需使用 throw; 重新抛出它们(这将创建一个重新抛出IL op,而不是trow)。
如果使用的资源不知道可能抛出什么类型的异常,那么您将被迫捕获常规异常类型。在这种情况下,保险箱的用途是使用来自不同应用程序域的所述资源(如果可能的话),或者让异常冒泡到最高级别(从UI)可以显示或记录它们。
其他提示
我认为使用 catch 块有以下三个原因:
- 您可以处理异常并恢复(从“低级”代码)
- 您想要重新包装异常(同样,来自“低级”代码)
- 您位于堆栈的顶部,虽然您无法恢复操作本身,但您不希望整个应用程序崩溃
如果你坚持这些,与 try/finally
块 - 以及那些 try/finally
块几乎总是只是调用 Dispose
, ,因此最好写成 using
声明。
底线:拥有一个非常重要的 finally
阻止释放资源,但是 catch
块通常应该更稀有。
>知道何时设置try / catch块。例如,您可以以编程方式检查可能在不使用异常处理的情况下发生的情况。在其他情况下,使用异常处理来捕获错误条件是合适的。
这就是我发现的东西,对我来说很有意义。手动检查明显的东西,让try-catch做其余的事情。
Eric Lippert有一个很好的博客,这里。
除非你能做一些有用的事情,否则没有必要(除了“烦恼”(见博客))捕捉异常;在大多数情况下,你根本就不能 - 所以让它泡泡(你的UI显然应该清理并显示一些东西)。
然而,您可能会有“尝试/最终”处理资源管理。甚至更清洁,“使用”或“使用”阻止做同样的事。
我认为绝对的答案是完全有条件的(你对环境的控制程度如何,性能和一致性之间的预期平衡是什么以及我确定的其他许多因素),但总的来说我总是这么做,选择安全性可能性能较慢。
它总是取决于你想要达到的目标。没有响应的服务器可能严重到足以阻止例程正在做的事情,并且应该向调用者抛出异常。
在其他情况下,您不关心是否未能更新数据库。然后消耗异常就可以了。
显然,您不希望向最终用户显示堆栈跟踪,因此您需要在某处捕获它。