【问题标题】:Does .NET has an Exception that similar to Delphi's EAbort?.NET 是否有类似于 Delphi 的 EAbort 的异常?
【发布时间】:2009-07-30 06:22:58
【问题描述】:

.NET 是否有类似于 Delphi 的 EAbort 的异常?

目前,我定义了自己的“AbortProcess”继承异常。 与忽略“AbortProcess”的 My.Application.UnhandledException 处理程序一起 我仍然想知道 .NET 中是否已经存在类似的机制。

Class AbortProcess
    Inherits System.Exception
End Class

Sub Abort()
    Throw New AbortProcess()
End Sub

Sub AppDomain_UnhandledException(ByVal sender As Object, ByVal e As ApplicationServices.UnhandledExceptionEventArgs)
    If TypeOf e.Exception Is AbortProcess Then
        e.ExitApplication = False
    End If
End Sub    

Sub PerformActions()
    Action1()
    If Not Action2() Then
        Abort()
    End If
    Action3()
    ...
End Sub

典型的 .NET 开发人员如何处理这个用例?

更新:

不幸的是,由于某些原因,许多人对这个问题投了反对票,但没有发表任何评论。我能弄清楚的唯一原因是他们可能认为 Exception 永远不应该用于控制程序流;我倾向于同意这一点。但是,我最近研究了 ANTLR,发现它们确实使用自定义异常 (RecognitionException) 作为控制流构造。结合 Python 的 StopIteration 用法,我相信使用 Exception 作为控制流构造实际上已经被广泛使用。它只是不像 Delphi VCL 那样被标准化。

【问题讨论】:

  • 哎呀!谁他妈的给我投反对票?!?!?!?我只是一个尝试进入.NET 编程的Delphi 程序员。我发现 .NET 中缺少一些 Delphi 概念,所以我在这里寻求正确的方法。这怎么了?!?!?!?

标签: .net delphi exception


【解决方案1】:

定义 Delphi 的 EAbort 异常类有两个特性。

  1. IDE 已预先配置为在检测到引发该类的异常时中断您的程序。
  2. 主应用程序异常处理程序可识别EAbort 及其后代,并且在捕获此类异常时不显示通常的消息框。

看起来您提出的代码完成了第二部分。您可以为第一部分配置 Visual Studio;请参阅另一个 Stack Overflow 问题的答案,Is there a better way to get Visual Studio to ignore try/catch in debug mode? 我不知道已经为此指定了任何异常类。

EAbort 异常旨在使程序停止运行它正在运行的任何事件或消息处理程序,并在主消息循环中恢复。但是,为了使其真正起作用,需要编写所有其他代码以正确处理异常。也就是说,他们需要使用 finally 部分来保持自己处于稳定和一致的状态,并且他们需要重新抛出或永远不会捕获他们无法真正修复的异常。

【讨论】:

    【解决方案2】:

    我知道的唯一一个是ThreadAbortException,它是“调用 Abort 方法时引发的异常。

    【讨论】:

      【解决方案3】:

      如果您想在 .Net 中快速退出应用程序,则异常不是最佳路径。您明确抛出的任何异常都可以被捕获和吞下。如果您使用正确的技巧,甚至可以捕获像 ThreadAbortException 这样的危险异常。

      快速退出应用程序的最佳方法是使用 Environment.Exit。

      那或故意创建堆栈溢出场景,因为它是由 CLR 抛出的不可捕获的异常(不提供自定义主机)。

      【讨论】:

      • 正如您将在代码示例中注意到的那样,这个假设的异常明确不是意味着终止应用程序。这意味着中止当前的事件处理程序并返回消息循环。
      【解决方案4】:

      这基本上是一个例外,只是作为快速退出功能。 .NET 异常并不打算这样做,吞下它们是非常糟糕的做法。

      不应使用异常来处理数据流。如果您认为某事可能会失败,您可能会抛出异常,然后在第一个适当的时刻捕获它。让异常落入 UnhandledException 函数并吞下它只是一种不好的做法,可能会使您的应用程序处于未知状态(因为异常发生的所有方法都将被“中止”)。

      在这种情况下,如果您需要在那个 sub 中出现异常,我会在调用时捕获它:

      try {
          PerformActions()
      } catch (AbortProcess) {
          //do some cleaning up or just ignore
      }
      

      这种方式可以在接近其来源的地方捕获异常,并且任何清理都仅限于该功能。所有其他异常都将传递给您的 UnhandledException 函数,您可以做的最好的事情就是报告错误并关闭应用程序。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-27
        • 2011-11-14
        • 2011-05-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-04
        • 2013-01-13
        相关资源
        最近更新 更多