【问题标题】:How can I gracefully exit my application on an error?如何在出现错误时优雅地退出我的应用程序?
【发布时间】:2010-11-17 00:37:18
【问题描述】:

这是一个问题,我在现实世界的编程经验不足。我有一个调用其他三个函数的函数:

Public Sub StartService()
    RunSearch()
    SaveMessages()
    DeleteMessages()
End Sub

RunSearch(), SaveMessages() and DeleteMessages() 的每个方法中,我使用 Try Catch 语句来捕获错误。现在,当RunSearch() 出错时,我捕获了错误并写入错误日志,但我也收到了来自SaveMessages()DeleteMessages() 的两个错误,因为这些函数依赖于RunSearch() 不返回错误。我正在尝试建立良好的错误捕获基础,因此我不想在出现错误时终止应用程序。我的问题是:如果RunSearch() 发生错误,我该如何优雅地停止执行。

【问题讨论】:

    标签: c# asp.net vb.net error-handling


    【解决方案1】:

    为什么RunSearch在记录问题后不重新抛出异常?

    如果您不想在RunSearch() 失败时调用SaveMessages(),请不要这样编码。

    我的一般想法是每个方法的接口都指定一个“协议”。它必须在出现问题时说明其行为。方法包括:

    1. 如果出现错误,我将终止进程。这非常极端,限制了您的方法的可重用性。
    2. 我会返回一个计数或状态码或类似的东西。由您决定是否检查以及任何特定状态代码是否意味着调用其他方法是安全的。我不想依赖客户端记住检查状态代码。
    3. 如果我失败了,我会留下一些东西,以便后续处理能够正常进行。例如,如果我的工作是创建一个链表,那么在发生错误时,我不会留下悬空指针或初始化列表。您可能会得到一个空列表,但至少格式良好的后续处理会起作用。这往往意味着与其他方法有某种程度的一致性(即耦合)。这通常是最好的方法,尤其是在结合良好的问题记录时。
    4. 如果我不能完成这项工作,我会抛出异常。异常将表明如果您再次调用 be (我经常使用 TransientException 和 InvalidRequestException),以后是否有可能工作。异常很有用,因为客户端不能(对于 Java 检查异常)意外地忽略它们。在处理诸如“无法打开数据库”之类的问题时,这似乎是合理的。我们真的不希望人们将“甚至无法访问数据库”误认为“此人没有犯罪记录”。

    【讨论】:

    • 另一个好建议。为你和@Rob Thijssen 竖起大拇指。
    • 啊。这个答案都是关于设计的。潜心编写代码非常诱人,但首先要考虑一系列事情(并记录答案)肯定会有所帮助。
    【解决方案2】:

    一种可能的选择是将 RunSearch 方法更改为返回布尔值 - 如果成功,则返回 True,如果发生会阻塞其他两个函数的错误,则返回 False。

    那么你可以这样做:

    Public Sub StartService()
        If RunSearch() Then
            SaveMessages()
            DeleteMessages()
        End If
    End Sub
    

    【讨论】:

      【解决方案3】:

      您可以在完成日志记录后重新抛出方法异常,然后将 RunSearch() 方法包装在 try/catch 块中,这样接下来的两个方法就不会运行。

      【讨论】:

        【解决方案4】:

        似乎您可能不需要低级方法级错误处理程序,而只需要一个高级/应用程序级处理程序。如果每个方法的所有 catch 块都相同,我建议切换到高级错误处理程序。作为一般规则,您只想捕获您可以显式处理的异常,或在最后机会捕获它们以进行日志记录,并防止 untidy 应用程序崩溃。

        这就是我的处理方式

        public void StartService()
        {
            try
            {
               RunSearch();
               SaveMessages();
               DeleteMessages();
            }
            catch(Exception ex)
            {
                //Do Nothing or Log ex
            }
        }
        
        public void RunSearch()
        {
        //No error handler here, as this method cannot recover from exceptions
        
        //RunSearch functionality
        }
        

        【讨论】:

        • 无意冒犯马特,但如果问题是来自被录取的初学者用 VB 提出的,我建议用 VB 回答。
        • @Rob。谢谢,忘记格式化@Bill。点明白了,但 OP 标记了问题 C# 所以假设它没问题
        【解决方案5】:

        您不应使用异常来控制程序流程。请改用返回值。抛出和捕获异常是昂贵的,并且应该只用于报告代码中真正的意外情况。

        David Stratton 的上述回答是一个更好的解决方案。

        【讨论】:

          猜你喜欢
          • 2012-02-22
          • 2013-07-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多