try catch语句的位置

时间:2014-02-05 19:06:28

标签: c#

我有一些目前看起来像这样的代码:

public void MainFunction() 
{
   try
   {
      SomeProblemFunction();
   }
   catch
   {
      AllFineFunction();
   }
}

private void SomeProblemFunction() { ... }
private void AllFineFunction() { ... }

正如您所看到的,我正在围绕SomeProblemFunction语句包含对try的调用,因为该函数可能会失败(它依赖于外部Web服务调用)。

我的问题是:try语句应该是a)问题函数之外(比如我现在有)或b)问题函数内部吗?

感谢。

6 个答案:

答案 0 :(得分:7)

通常,您希望允许异常传播到应用程序边界。除了你的例外,你只想做一些事情之一:

  • 包裹它
  • 替换它
  • 让它传播

<强>更新

从您的问题来看,您似乎正在为Web服务调用寻找容错解决方案。这是一个更复杂的问题,而不仅仅是“我在哪里试试看?”您仍然可以将异常处理放在应用程序边界,但是您可以实现容错策略。这需要考虑很多因素,包括异步调用您的Web服务,重试尝试次数等。我建议您搜索Web服务容错。

答案 1 :(得分:4)

你拥有的是正确的;请参阅MSDN example

public class ThrowTestB
{
    static void Main()
    {
        try
        {
            // TryCast produces an unhandled exception.
            TryCast();
        }
        catch (Exception ex)
        {
            // Catch the exception that is unhandled in TryCast.
            Console.WriteLine
                ("Catching the {0} exception triggers the finally block.",
                ex.GetType());

            // Restore the original unhandled exception. You might not 
            // know what exception to expect, or how to handle it, so pass  
            // it on. 
            throw;
        }
    }

    public static void TryCast()
    {
        int i = 123;
        string s = "Some string";
        object obj = s;

        try
        {
            // Invalid conversion; obj contains a string, not a numeric type.
            i = (int)obj;

            // The following statement is not run.
            Console.WriteLine("WriteLine at the end of the try block.");
        }
        finally
        {
            // Report that the finally block is run, and show that the value of 
            // i has not been changed.
            Console.WriteLine("\nIn the finally block in TryCast, i = {0}.\n", i);
        }
    }
    // Output: 
    // In the finally block in TryCast, i = 123. 

    // Catching the System.InvalidCastException exception triggers the finally block. 

    // Unhandled Exception: System.InvalidCastException: Specified cast is not valid.
}

答案 2 :(得分:2)

我认为这是一个很好的问题。我会尝试回答。


如果您想在 SomeProblemFunction中恢复,那么将try...catch移到该方法内部是完全合理的。但是,如果您觉得如果SomeProblemFunction中的任何内容失败,那么整个事情就是失败,然后保持现状,然后恢复(或从中抛出)MainFunction。< / p>


感谢下面的评论,我添加了一些清晰度。根据{{​​1}}内引发的特定异常,您可能无法在该方法中恢复。如果你有可恢复和不可恢复的混合,那么在两个地方都有SomeProblemFunction是明智的。

最重要的是你从不捕获一个异常,在你做完事情之后你无法恢复它。添加大量广泛的捕获量(try...catch)以避免您的应用程序在开发过程中崩溃是很诱人的,但它永远不值得。如果这些东西成为您的生产代码,那么您已经引入了解决问题和调试的噩梦。

答案 3 :(得分:2)

根据经验,我尝试构建代码,将尝试捕获集中在可能出现问题的确切位置。

那说你的两个解决方案都是正确的。

如果是我的代码,我会这样做

public void MainFunction() 
{
   try
   {
      SomeProblemFunction();
   }
   catch(Exception e)
   {
      Messagebox.Show(e.Message);
   }
}

private void SomeProblemFunction() {
    try{
        web call
    }
    catch{
         throw a specific exception related to this spot
    }
}
private void AllFineFunction() { ... }

使用此方法,您可以轻松创建处理大量非常准确异常的应用程序

答案 4 :(得分:1)

在我看来,对此没有直接的答案。 try catch用于处理可能发生的异常。如果您的异常处理代码在main函数中,那么您应该在main函数中使用try catch。如果问题函数中的异常处理代码,则应将其添加到问题函数中。

我的偏好是把它放在两个功能中。如果将try catch放在问题函数中,则可以抛出异常并将其捕获到main函数中。对于其他开发人员来说,这个异常在该函数中被认为是错误的并且不会错过处理它。

答案 5 :(得分:1)

这取决于此Web服务调用失败的严重程度。

是否会阻止您的代码进一步处理?如果是这样,请不要尝试/捕获,允许它传播给需要知道此Web服务调用失败的人。或者,您仍然可以使用一些更有意义的异常类型/详细信息来捕获并抛出新异常。

如果它不起作用,您只是想再次尝试重新尝试Web服务吗?如果是这样,那么你可以在正确的地方尝试;你只需要添加一个循环。

如果此Web服务调用失败,这不是一件大事吗?例如 - 你的其余代码能正常工作吗? (我发现这不常见)。如果是这样,请将try / catch保留在原处,并将错误记录到某处,以便您收到警报。