如何在出错时优雅地退出我的应用程序?

时间:2009-08-05 13:36:02

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

这是一个我的真实世界编程缺乏经验的问题。我有一个函数可以调用其他三个函数:

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

在每个方法RunSearch(), SaveMessages() and DeleteMessages()中我使用Try Catch语句来捕获错误。现在我抓住错误并在RunSearch()错误时写入错误日志,但我也从SaveMessages()DeleteMessages()得到两个错误,因为这些函数依赖于{{1不返回错误。我正在尝试建立一个错误捕获基础的好,所以我不只是想在出现错误时杀死应用程序。我的问题是:如果RunSearch()发生错误,我怎样才能优雅地停止执行。

5 个答案:

答案 0 :(得分:5)

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

如果SaveMessages()失败,如果您不想拨打RunSearch(),请不要这样编码。

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

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

答案 1 :(得分:3)

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

然后你可以这样做:

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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

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

这就是我接近它的方式

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
}

答案 4 :(得分:0)

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

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