如果catch块包含continue语句,finally块何时执行?

时间:2012-06-26 03:30:46

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

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

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块中抛出异常,此代码是否会(尝试)删除正确的文件?或者,在finally块运行之前,catch语句中的continue是否生效?

4 个答案:

答案 0 :(得分:13)

将其视为具有catch表达式可选的try / finally块。代码中的两个continue语句都会将执行堆栈弹出catch,这会在允许循环继续之前将执行放在finally块中。任何时候有一个try / finally块,最后总会被执行。

答案 1 :(得分:8)

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

答案 2 :(得分:6)

finally将作为try完成之前的最后一步执行。因此它将在合适的时间发生。为了便于概念化,请考虑如果所有continue语句都被return替换会发生什么 - finally仍会执行。

答案 3 :(得分:6)

来自C# Language Specification

  

8.9.2继续声明

     

...

     

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

     

continue语句执行如下:

     

·如果continue语句退出一个或多个try块   关联最后块,控制最初转移到   最后阻止了最里面的try语句。什么时候控制   到达finally块的终点,控制转移到   下一个封闭的try语句的finally块。这个过程是   重复,直到所有介入的try语句的finally块   已被执行。

     

...