【问题标题】:C# try catch continue executionC# try catch 继续执行
【发布时间】:2012-06-04 21:58:27
【问题描述】:

我有一个看起来相当简单的问题(当然,如果你知道答案的话)。

某个函数我调用了另一个函数,但我想从调用者继续执行,即使被调用者抛出了异常。举个例子吧:

something function1()
{
    try
    {
        //some code
        int idNumber = function2();
        //other code that need to execute even if function2 fails
        return something;
    }
    catch(Exception e)
    {//... perhaps something here}
}

编辑:function1 也有一个 return 语句,所以实际上没有任何东西会在途中崩溃

在function2中我需要做一些事情,但我只需要在失败时记录,例如:

int function2()
{
    try
    {
        //dostuff
    }
    catch(Exception e)
    {
        //Log stuff to db
    }
}

好的,现在我的问题是,如果我想在函数1中继续执行,即使函数2抛出错误,我该怎么办?

有时,如果我应该投掷,我会混淆;或抛出 e;或者什么都不扔(将 catch 块留空)

【问题讨论】:

  • 没什么。由于您已经在函数 2 中处理了异常,前提是您不在函数 2 的 catch(...) 中重新抛出异常

标签: c# try-catch


【解决方案1】:

为什么不能使用 finally 块?

喜欢

try {

} catch (Exception e) {

  // THIS WILL EXECUTE IF THERE IS AN EXCEPTION IS THROWN IN THE TRY BLOCK

} finally { 

 // THIS WILL EXECUTE IRRESPECTIVE OF WHETHER AN EXCEPTION IS THROWN WITHIN THE TRY CATCH OR NOT

}

修改问题后编辑:

你可以这样做:

int? returnFromFunction2 = null;
    try {
        returnFromFunction2 = function2();
        return returnFromFunction2.value;
        } catch (Exception e) {

          // THIS WILL EXECUTE IF THERE IS AN EXCEPTION IS THROWN IN THE TRY BLOCK

        } finally { 

        if (returnFromFunction2.HasValue) { // do something with value }

         // THIS WILL EXECUTE IRRESPECTIVE OF WHETHER AN EXCEPTION IS THROWN WITHIN THE TRY CATCH OR NOT

        }

【讨论】:

  • 好吧,因为 function1() 还需要返回其他内容。让我编辑我的帖子来演示:)
  • 我知道你在那里做了什么,这非常聪明。我面临的问题是 function1() 也必须返回一个语句,因此我必须在从 function2() 捕获后继续,因为 finally 块不能包含返回语句:)
  • 可以在finally块中计算return语句,之后返回。 finally 块之后的东西也会执行。
  • 确实如此。我在 function1() 中的其他代码以及 return 语句当然可以在 finally 块之后运行。但是 function1() 中的 catch 块不会停止所有执行(不包括 finally 块)吗?问题是,如果我不完全改变我的代码,即使 function2() 会抛出异常,function1() 中的 return 语句也不会被中断。
  • finally 语句无论如何都会执行。当抛出未处理的异常时,执行停止。您正在处理 try-catch 块中的异常。即使 function2 抛出异常,您仍在处理它,然后像往常一样从 function1 返回。
【解决方案2】:

或者您可以将循环逻辑本身封装在 try catch 中,例如

for(int i = function2(); i < 100 /*where 100 is the end or another function call to get the end*/; i = function2()){

    try{
     //ToDo
    }
    catch { continue; }    

}

或者……

try{ 
    for(int i = function2(); ; ;) {
        try { i = function2(); return; } 
        finally { /*decide to break or not :P*/continue; } }
} catch { /*failed on first try*/ } finally{ /*afterwardz*/ }

【讨论】:

  • 这如何回答这个问题?
  • 我想弄清楚 100 代表什么。你的意思是 100 是跳出循环的方式(或者我为 100 跳出的任何东西)?
  • 但是为什么要使用循环呢?问题中没有提到function2需要重复调​​用
  • 我认为它正在返回一个与假定的以后操作相关的索引...我只是假设...而 100 将是您不想过去的...这只是一个交替……不需要敌意!我投票赞成我只想记录在案的当前答案!
  • 谢谢你们的投入,记住我们都是朋友;)我现在真的明白你对这个for循环的意思了,非常聪明。实际上 function2() 正在为我做的事情是尝试创建东西,如果它抛出异常我基本上不会在意,我只想记录它。 (因此只需继续执行)。我可能需要重新考虑我的一些代码才能继续:)
【解决方案3】:

将 catch 块留空应该可以解决问题。不过,这几乎总是一个坏主意。一方面,存在性能损失,另一方面(这一点更重要),您总是想知道何时出现错误。

我猜想,在你的情况下,“被调用者”函数失败实际上不一定是“错误”,可以这么说。也就是说,预计它有时会失败。如果是这种情况,几乎总有比使用异常更好的方法来处理它。

,如果你能原谅双关语,例外“规则”,不过。例如,如果 function2 要调用的 Web 服务的结果对于您的页面来说并不是真正需要的,那么这种模式可能没问题。尽管在几乎 100% 的情况下,您至少应该将其记录在某个地方。在这种情况下,我会将其记录在 finally 块中并报告服务是否返回。请记住,现在可能对您没有价值的数据可能会在以后变得有价值!

最后一次编辑(可能):

在评论中我建议你将 try/catch inside 函数2。只是想我会详细说明。 Function2 看起来像这样:

public Something? function2()
{
    try
    {
        //all of your function goes here
        return anActualObjectOfTypeSomething;
    }
    catch(Exception ex)
    {
        //logging goes here
        return null;
    }
}

这样,由于您使用可为空的返回类型,因此返回 null 不会对您造成伤害。

【讨论】:

  • 是的,我开始倾向于别的东西,我想先用 stackoverflow。但既然你提到它,我想我可能不得不重新考虑我的代码:)
  • 可能是这样!不过规则有例外——请阅读我的最后一次编辑
  • 这是个好建议,无论如何我都应该记录这些内容。随着时间的推移,任何收集到的信息当然会很好:) 问题是 function1() 还需要返回 að 语句,因此我可能会听取您的建议并重新考虑我的代码。
  • 好吧,就重新考虑您的代码而言,我建议将您的 try/catch 迁移到 inside 函数 2。这样,无论哪种方式,它都会返回一些内容并继续执行.
  • 另外,如果这是最有帮助的答案,请记住将其标记为 :)
【解决方案4】:

就这样做

    try
    {
        //some code
     try
     {
          int idNumber = function2();

     }
     finally
     {
       do stuff here....
     }
    }
    catch(Exception e)
    {//... perhaps something here}

出于所有意图和目的,finally 块将始终执行。现在有几个异常实际上不会执行:任务终止程序,还有一个快速失败安全异常会立即终止应用程序。除此之外,函数 2 中将抛出异常,finally 块将执行所需的代码,然后在外部 catch 块中捕获异常。

【讨论】:

  • 这不会在 function2() 上失败并跳过//其他需要执行的代码吗?
  • fanally 块在执行 try 和 catch 块后执行
  • 嗯....我的想法完全正确。但是 finally 块应该涵盖其余部分。出于所有目的,尽管 function2() 失败,我仍需要继续...
  • 是的,您的编辑解决了我所说的问题。我认为这只是一个错字
  • 另外,只是因为它是我最讨厌的,它的“所有意图和目的”:)
【解决方案5】:

在您的第二个函数中,删除 catch 块中的 e 变量,然后添加 throw。

这会将生成的异常传递给最终函数并输出。

当您不希望您的业务逻辑代码抛出异常但您的 UI 时,这很常见。

【讨论】:

    【解决方案6】:

    你的意思是不管function2是否抛出异常,你都想在function1中执行代码?你看过finally块吗? http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx

    【讨论】:

    • 是的,我已经编辑了我的帖子,我需要让 function1() 也返回另一个语句,这样我就不能在 finally 块中包装 return 语句(抱歉之前没有说明)跨度>
    猜你喜欢
    • 2013-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多