【问题标题】:Exception throwing from C# modulesC# 模块抛出异常
【发布时间】:2012-04-16 00:34:45
【问题描述】:

我们的应用程序是模块化的(一组做特定事情的模块)。这些模块具有事件处理程序。这些事件可以从其他模块或应用程序菜单中触发。

情况:

模块 A(具有 UI)收到一个事件“deleteitem”。事件参数应包含要删除的项目名称。但在这种情况下,它是空的。在某个地方,有人搞砸了。

问题:

模块应该抛出吗?请记住,该模块将在事件处理程序中抛出,并且可能会使应用程序崩溃,因为模块编写者不知道是否处理了异常。

上述场景是一个更大的问题的快照,该问题涉及从模块抛出异常,这可能导致应用程序崩溃。反对它的论点是应用程序可以在没有特定模块的情况下继续工作。那么,谁应该确保 - 模块或应用程序?

【问题讨论】:

  • 如果不抛出还会发生什么,你想要吗?
  • 如果没有抛出,应用程序将继续。我想要那个吗?-这就是问题所在。我不希望那样,因为我知道某处有问题。计数器参数是让应用程序继续,因为应用程序可以在没有模块执行操作的情况下继续。

标签: c# wpf modularity


【解决方案1】:

如果项目名称应该始终存在并且它是 null 是一种例外情况,不应该发生,您应该抛出,因为现在您的应用程序处于未知状态永远不应该发生的状态

如果调用者可以从中恢复,他们将编写自己的异常处理例程来处理它。

【讨论】:

  • 这也是我的想法。 Maciej 的回答是我同事的反驳。
  • 应该在这里提出一个实际的异常,比如这个。如果合适,可以记录异常并在堆栈的上层忽略该异常。
  • @Jodrell - 好吧,如果尝试访问传递的null 参数的成员,则会抛出异常
  • @Oded,真的,我同意。我的意思是说,不要捕获和抑制异常,给调用者一个函数有效的印象。您可以记录并抑制以防止在顶部显示给用户一次。 stackoverflow.com/questions/1472498/…
  • @Oded。您如何看待将 IApplicationErrorHandler 接口注入模块?模块可以从接口调用 Reporterror(type)。这样模块可以报告错误,但接口实现可以决定应用程序是否应该继续
【解决方案2】:

这是一个重要的事件吗?你能忽略它吗?我会将其视为空事件并忽略它。我想不能删除某些东西不是关键任务。最好将此信息记录为警告或错误,以便您知道它发生了。

我的规则是,如果可以重新发布某些内容,则不是必需的,但如果不能,则很重要。但这可能会根据特定的应用程序上下文而改变。

坏事发生了,如果可以的话,你应该尝试从它们中恢复过来。我的首要任务是确保应用程序(模块)即使输入错误的数据也不会崩溃,但绝对要确保你知道发生了坏事(日志记录)。如果您束手无策,无能为力,例外是最后的手段。

我在此处描述的内容最适用于分离的模块,例如 WCF 服务。如果它都在一个应用程序中(模块是类),最好的办法是返回一个异常,但确保调用者可以处理它。所以模块分离在这里很重要——分离越多,错误恢复能力就越大。 WCF 服务或 Windows 服务不应崩溃。

【讨论】:

  • 这正是我同事的说法。那么,是否可以丢弃应用程序要求您的模块执行操作的错误状态?
  • 刚刚在我的回答中添加了更多内容。坏事发生了,如果可以的话,你应该从中恢复过来。如果您无能为力而无能为力,例外是最后的手段。
  • 我强烈建议不要忽略该错误。正如 Oded 在他的回答中提到的那样,该应用程序现在处于未知状态。您无法控制进一步执行将导致什么。如果你很幸运,你最终会遇到另一个很难知道其根本原因的异常。如果你不那么幸运,你最终会得到损坏的用户数据。
  • @MaciejDopieralski 所以,如果我的应用程序可以继续运行而没有任何人抱怨错误情况,而且将来还会出现更多错误,那么随着时间的推移,应用程序会变得越来越不稳定。可以吗?
  • 再次,取决于事件的重要性。在任何一种情况下都不要忽略它。确保日志通过以告知问题。但是在我看来,崩溃的 UI 是最后的手段,如果发生了不可恢复的事情(比如不是配置或磁盘错误等),它应该会发生。
【解决方案3】:

投掷。通过修复引发格式错误事件的模块来对任何此类异常做出反应,一旦发现它们。

答案部分取决于您如何构建和版本化产品(触发事件的模块是否与所有侦听器一起维护和构建)。

因为您描述的是一种非常极端的行为,表明存在产品缺陷,所以尽早发现它是件好事。如果您没有更好的方法来提醒任何正在使用或测试有缺陷软件的人,那就扔掉吧。

另一方面,不要在不太极端的情况下抛出,例如当事件可能形成良好时,或者当你自己的模块可能对它负责时。

如果相对较早地发现产品缺陷,修复成本最低;但是过度抛出可能会导致缺陷传播到不相关的模块(将接收一些但不是所有相关事件),从而延迟固定缺陷。

【讨论】:

  • 我也这么认为。我在模块中遇到了一个事件,它要求我做一些我不能做的事情,并且清楚地表明了应用程序中的某个错误。我认为最好尽早知道这一点,而不是继续使用不稳定的应用程序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-27
  • 1970-01-01
  • 1970-01-01
  • 2017-07-01
  • 2015-08-04
  • 1970-01-01
相关资源
最近更新 更多