【问题标题】:Is it good to use try catch within a try catch? [duplicate]在 try catch 中使用 try catch 好吗? [复制]
【发布时间】:2012-11-25 10:26:19
【问题描述】:

可能重复:
Are nested Try/Catch blocks a bad idea?

目前我在 try catch 中使用 try catch ?当前的场景在我们的应用程序中需要它。

void MyFun()
{
    try
    {
        //Process logic 1
        // ......
        try
        {
            //Process logic 2
            // ......
        } catch (Exception ex)
        {
            //write an error details in database
        }

        //Process Logic 3
        // ......

    } catch (Exception ex)
    {
        //show error msg
    }
}

【问题讨论】:

标签: c# asp.net .net c#-4.0


【解决方案1】:

这个项目表明它不是一件坏事,你只需要以其他方式处理错误。

Exception handling try catch inside catch

【讨论】:

    【解决方案2】:

    这没有什么特别的问题,特别是如果您想以不同的方式处理异常。
    但是,如果内部异常和外部异常分别属于不同类型的E1, E2 并且E1 不是E2 的父级,则可以有两个相邻的catch 子句。

    try
    {
      // do something
    }
    catch (E1 e1)
    {
    }
    catch (E2 e2)
    {
    }
    

    正如 Rob 和 J.Steen 所指出的 - 这与问题中的情况略有不同,因为在这种情况下,E1 在代码不会被执行后被抛出。

    【讨论】:

    • 这在语义上是不一样的,因为他注意到在内部 catch 块之后有处理逻辑。
    • 如果proccess logic 1 和process logic 3 只抛出E2 而process logic 2 抛出E1 是一样的。
    • 我想,但是为什么要首先写代码呢?
    • @Rob 写什么代码?
    • 没有。如果流程逻辑 2 抛出异常,流程逻辑 3 将永远不会执行。不一样。
    【解决方案3】:

    在不知道这里有什么逻辑的情况下回答这个问题有点困难。 当然,在性能方面,嵌套异常处理会产生更大的成本,但一般的经验法则是只捕获作为开发人员了解如何处理的异常。这与 TDD 的实践重叠,如果您有一组足够好的测试,您可以确定预期的异常应该在哪里,那么这将决定您的异常逻辑。

    【讨论】:

      【解决方案4】:

      我想说:这还不错。它是否好取决于你的程序,以及考虑到你的方法的逻辑和契约,这样的概念是否有意义。

      编辑:我建议查看文章Exception Cost: When to throw and when not to。它概述了 CLR 中异常管理最昂贵的部分。

      【讨论】:

      【解决方案5】:

      我不明白为什么不。如果您在 catch 中有可能失败或引发需要处理的异常的逻辑,那么这是有道理的。

      【讨论】:

        【解决方案6】:

        嵌套的 try/catch 很好。您要远离的是基于 try catch 更改代码的逻辑流程。换句话说,您不应该将 try/catch 视为 if/else 块。所以这并不理想:

        //over the top example just to demonstrate my point
        
        public bool IsNumberTen(int x)
        {
            try
            {
                if(x > 10)
                    throw new NumberTooHighException();
                else if(x < 10)
                    throw new NumberTooLowException();
                else
                    return true;
        
            }
            catch(NumberTooHighException)
            {
                return false;
            }
            catch(NumberTooLowException)
            {
                return false;
            }
        }
        

        【讨论】:

        • 这真的是把例外情况当作 if/else 处理吗?将 func1() 替换为 File.Open(path) 并将 func2() 替换为 MessageBox.Show("I could't open your file.") - 它不会将其视为 if-else。
        • 也许我举了一个不好的例子。我会想出一个更好、更明确的。
        • @Rob,查看我更新的示例
        【解决方案7】:

        我正在尝试考虑您可能需要嵌套块的情况......也许如果您正在更改数据库并且您正在使用 try catch 作为虚拟事务,您可能想要尝试更新一些属性,但随后如果失败则继续,但如果您实际提交数据库更新本身,也会捕获一个整体异常。

        即使考虑到这一点,您也不应该这样做......像这样简单地将块彼此相邻堆叠应该完全足够了:

        void MyFun()
        {
            try
            {
                //Process logic 1
                // ......
            } catch (Exception ex)
            {
                //show error msg
            }
            try
            {
                //Process logic 2
                // ......
            } catch (Exception ex)
            {
                //write an error details in database
            }
        

        }

        还可能值得注意的是,如果您发现需要嵌套 try catch 块,那么您可能有更好的方法来设计您的代码。

        编辑: Itay 的答案也比嵌套要好一些,尽管一旦你发现异常,它就不允许你继续进行。

        希望这会有所帮助!

        【讨论】:

        • 提示:当您谈论其他答案时,“低于”或“高于”实际上并不适用。我可以用各种方式对这个答案列表进行排序。但现在我只是在吹毛求疵。 =)
        猜你喜欢
        • 2016-05-27
        • 2012-05-27
        • 1970-01-01
        • 2014-11-27
        • 2021-01-15
        • 1970-01-01
        • 1970-01-01
        • 2021-11-25
        • 2013-11-07
        相关资源
        最近更新 更多