C#事件处理程序应该是异常安全的吗?

时间:2010-02-24 19:24:39

标签: c# .net

假设一个事件有多个处理程序,如果任何事件处理程序抛出异常,则不执行其余处理程序。

这是否意味着事件处理程序永远不应该抛出?

6 个答案:

答案 0 :(得分:12)

由于调用事件意味着调用者不了解被调用者:

  1. 在面对任意异常时,调用事件处理程序应该是健壮的。调用堆栈中的所有内容都需要正确清理自己的混乱,以防万一出现意外情况。

  2. 事件处理程序应该避免抛出异常。

  3. 像空引用异常这样的东西在任何代码中都是不可原谅的,所以显然我们并不关心它。

    文件IO异常之类的东西总是在写入或读取文件时发生,因此我会避免在事件处理程序中执行IO。如果在事件处理程序中执行IO是有意义的,那么它也会让senst处理处理程序中的IO异常。不要将其传播回来电者。找到一些方法来处理它。

答案 1 :(得分:9)

在理想的世界里,是的。尝试设计事件处理程序以便它们:

是个好主意
  • 不要抛出异常
  • 执行得非常快

不这样做会导致意外的副作用,因为事件的其他订阅者可能永远不会收到消息,或者很晚才收到消息。

答案 2 :(得分:5)

不应该在事件处理程序中吞下异常,但我通常也不建议抛出它们。问题是,从事件处理程序中抛出 catch 异常通常没有好处。

事件处理程序的设计模式会导致一些潜在的问题,因为它们都是间接调用的,可以是多播的。由于它们是间接的,因此您必须小心并计划可以捕获它们可能引发的异常的位置。由于它们是多播的,因此处理程序中的异常可能导致其他处理程序从未接收到该事件。

答案 3 :(得分:3)

为什么事件处理程序与其他模式不一样?有什么不同?例外意味着子程序告诉调用者它无法正常工作。这意味着调用者必须对其执行某些操作。如果一个处理程序正在执行一些对用例至关重要的处理,那么当它崩溃时,其他程序必须停止是明智的。

答案 4 :(得分:2)

这很有诱惑力但最终取决于具体情况。

  • 如果您希望程序崩溃而不是冒着在错误或奇怪状态下运行的风险,那么无论如何都要抛出异常。
  • 如果你真的不在乎(仔细思考这个)并且只需要注意异常,那么在try / catch块中包装就非常有意义了。
  • 如果你想让所有事件处理程序在崩溃之前运行(例如,某些处理程序可能会释放资源),那么它需要更多努力...

答案 5 :(得分:1)

在ASP.NET应用程序中,我只是让事件处理程序抛出异常。这些异常将允许ASP.NET的自定义错误页面功能工作。

在桌面应用程序中,我总是在任何事件处理程序的内容周围添加try / catch / finally块。这样,任何异常总是被记录并显示给最终用户,但永远不会逃避事件处理程序,因此它们不会使应用程序崩溃。