不处理异常是一个更好的主意

时间:2010-09-19 18:33:12

标签: c# exception-handling

1)

  

1 - 仅处理您的例外情况   实际上可以做些什么,和   2 - 您无法对绝大多数异常做任何事情

a)我假设“By not handling an exception”文本建议我们应该让异常在堆栈中冒泡,运行时将中止我们的应用程序?!

b)但是为什么让运行时中止异常优先于捕获异常,记录它然后通知用户失败?只有两者之间的区别在于,在后一种情况下,应用程序不会中止

例如,如果数据库出现故障,为什么整个程序崩溃(由于没有处理异常),如果我们可以反而捕获异常,记录它并通知用户失败,那样我们就可以保持程序并且正在运行

2)如果您知道某些代码块可能引发的异常无法处理,您是否应将此代码包含在try-finally块中,或者最好将其置于任何try-finally之外块?

谢谢

7 个答案:

答案 0 :(得分:8)

不,指南不是为了捕捉您对无法做任何事情的例外情况,除非在您的应用程序或主题的顶级

您应该尽量避免让您的应用程序崩溃 - 在某处记录信息,向您的用户说明解释发生的事情,并告诉他们如何向您报告错误。也许还尝试将未保存的数据保存在恢复文件中,以便下次应用程序启动时可以提供尝试恢复丢失工作的选项。

答案 1 :(得分:2)

尝试以这种方式查看...数据库出现故障。你怎么知道的?因为你得到超时/异常/某事。但你的应用程序可能不会得到例外。 ADO.NET/Linq到SQL /实体框架/无论您使用什么数据提供程序实际上是获取异常并将其抛给您的应用程序。对我来说,这就是建议的建议:作为一个组件设计师,我更喜欢抛出你无能为力的例外。

对于数据库示例,ADO.NET数据提供程序可以执行哪些操作?它可以带回服务器吗?修复网络连接?重置权限?不。所以它没有处理异常,它抛出它。

您引用的指南是组件开发,而不是运行时边界(线程或应用程序)的外边缘。在那个级别,做出如何处理已经冒泡的异常的决定是正确的。

答案 2 :(得分:1)

我认为你引用的人建议你应该让异常在堆栈中冒泡,直到更高层可以理解它直到它到达调用堆栈的顶部你的代码是记录它,或者向用户显示错误信息然后退出你的程序,如果它是致命的,或继续执行,如果它不是。

有时候最好不要继续执行程序 - 如果你得到一个OutOfMemoryException或其他一些程序操作未定义的情况 - 这是一个潜在的灾难。

答案 3 :(得分:1)

关键是你不希望在你的代码中嵌套try / catch块,因为这往往会隐藏你的代码问题。最好只在你理解错误和期望结果的情况下实现异常处理,否则不要处理它并让它冒泡。

至于冒泡的错误,你应该有一个全局异常处理程序来处理这些未捕获的应用程序错误。这仅在您的应用程序中的一个位置实现,并允许您将错误记录或呈现给用户。同样,这只在您的应用中的一个位置实现,并通过挂钩application.error事件来实现。

挂钩.net win表单应用程序的事件:

AppDomain.CurrentDomain.UnhandledException

挂钩.net asp.net应用程序的事件:

HttpApplication.Error

享受!

答案 4 :(得分:1)

我认为

的关键
  

只处理您可以实际执行某些操作的异常

如果您可以从应用程序中的那一点继续,那么您应该只处理异常。

采取一个简单的例子。

如果您正在用户系统上查找某个文件,并且该文件不存在,则应该提出“找不到文件”例外。现在,如果你可以从中恢复(比如简单地重新创建文件),那么就这样做并继续。但是,如果无法重新创建文件,则不应让程序继续运行。

但是,这并不意味着您不能在主程序中使用顶级捕获所有异常处理程序来向用户显示友好消息,可能是记录异常甚至将其邮寄给开发人员。 / p>

答案 5 :(得分:1)

这种说法是正确的。但它是在更深层次的应用程序中捕获异常的参考。基本上我们编写的大多数代码都不需要异常处理。只有应用程序的客户端部分负责捕获错误并将其呈现给用户 - 以及日志记录。

例如,可以在Web应用程序中使用相同的业务代码/数据库代码,并且windows / wpf应用程序和日志记录/处理可能会有所不同,更深层次的层不知道如何处理这些因此需要将责任留给UI层

答案 6 :(得分:1)

如果不了解这两个语句的上下文,请说两个语句都适用于方法和类,那么它们就有意义了:

调用方法的一段代码只能处理有关上下文的足够信息的异常。在大多数情况下,一段代码将没有足够的信息来处理所有异常。

示例:调用方法SaveData()的一段代码在知道时可以处理DatabaseStorageException,它将数据保存到数据库中。另一方面,如果代码片段以存储不可知的方式编程,那么捕获这样的特定异常并不是一个好主意。在这种情况下,最好让异常弹出callstack并让其他代码处理异常,该异常具有足够的上下文信息来处理它。