【问题标题】:When does a finally block execute if the catch block contains a continue statement?如果 catch 块包含 continue 语句,finally 块何时执行?
【发布时间】:2012-06-26 03:30:45
【问题描述】:

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

foreach(var obj in collection)
{
   try
   {
      // WriteToFile returns the name of the written file
      string filename = WriteToFile(obj); 
      SendFileToExternalAPI(filename);
   }
   catch ( ArbitraryType1Exception e )
   {
      LogError(e);
      continue;
   }
   ...
   catch ( ArbitaryTypeNException e )
   {
      LogError(e);
      continue;
   }
   finally
   {
      try
      {
         File.Delete(filename);
      }
      catch (Exception e)
      {
         LogError(e);
      }
   }
}

目标是尝试为集合中的每个对象写出一个临时文件,尝试将该文件加载到需要文件名的外部 API,然后在完成后清理临时文件。如果在将文件写入磁盘或将其加载到外部 API 时发生错误,我只想记录错误并转到下一个对象;我不能问用户该怎么做。

当您在 catch 处理程序中有 continue 语句时,我有点不确定 finally 块的时间是如何工作的。无论 try 块中是否抛出异常,这段代码是否会(尝试)删除 正确的文件?还是 catch 语句中的 continue 在 finally 块运行之前生效?

【问题讨论】:

    标签: c# control-flow try-catch-finally


    【解决方案1】:

    把它想象成一个 try/finally 块,带有可选的 catch 表达式。代码中的两个 continue 语句都会将执行堆栈从 catch 中弹出,这会将执行放在 finally 块中,然后再允许循环继续。任何时候有 try/finally 块,finally 都会被执行。

    【讨论】:

    • 我接受了这个解决方案,因为它包含关于 when finally 块相对于 continue 语句执行的最清晰的描述。
    【解决方案2】:

    无论是否抛出异常,都会执行您的 finally 块。因此,您的 finally 块将始终被执行。

    【讨论】:

      【解决方案3】:

      finally 将作为try 完成之前的最后一步执行。因此它会在正确的时间发生。为了更容易概念化,想想如果所有 continue 语句都被 return 替换会发生什么 - finally 仍然会执行。

      【讨论】:

        【解决方案4】:

        来自C# Language Specification

        8.9.2 继续语句

        ...

        continue 语句不能退出 finally 块(第 8.10 节)。当一个 continue 语句出现在 finally 块中,即 continue 语句必须在同一个 finally 块中;否则 发生编译时错误。

        一条 continue 语句执行如下:

        · 如果 continue 语句退出一个或多个 try 块 关联的 finally 块,控制最初转移到 finally 块最里面的 try 语句。何时以及是否控制 到达 finally 块的终点,控制转移到 下一个封闭的 try 语句的 finally 块。这个过程是 重复直到所有介入的 try 语句的 finally 块 已经被处决了。

        ...

        【讨论】:

          猜你喜欢
          • 2020-02-22
          • 1970-01-01
          • 1970-01-01
          • 2014-07-16
          • 1970-01-01
          • 2021-07-10
          • 1970-01-01
          • 2020-06-17
          • 2018-11-20
          相关资源
          最近更新 更多