2009-08-05 43 views
2

这是一个问题,我的现实世界编程经验不足闪耀。我有一个功能,这使得调用其他三个功能:我该如何优雅地退出我的应用程序出错?

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

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

回答

5

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

如果你不想拨打SaveMessages()如果RunSearch()失败,那么不要这样编码。

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

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

另一个很好的建议。竖起大拇指,并为你和@Rob Thijssen upvote。 – David 2009-08-05 13:43:27

+0

啊。这个答案是关于设计的。编写代码是很有吸引力的,但它确实有助于首先考虑一些事情(并记录答案)。 – Bill 2009-08-05 14:07:15

3

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

然后,你可以这样做:

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

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

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 
} 
+0

如果你缩进你的代码4个空格,我们得到的语法突出显示... – grenade 2009-08-05 14:14:53

+0

没有冒犯马特,但如果问题是在VB从一个被承认的初学者,我建议在VB中回答。 – Bill 2009-08-05 14:31:36

+0

@Rob。谢谢,忘了格式化 @Bill。理解点,但OP标记了C#这个问题,所以假设它是可以的 – MattH 2009-08-05 14:40:57

0

你不应该使用异常来控制程序流程。改用返回值。投掷和捕捉异常代价昂贵,只能用于报告代码中真正意想不到的情况。

大卫斯特拉顿的上面的答案是一个更好的解决方案。