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



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

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 语句时,最终块的时间是如何工作的。无论 try 块中是否引发异常,此代码是否会(尝试)删除正确的文件?还是 catch 语句中的继续在最终块运行之前生效?

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

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

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

来自 C# 语言规范:

8.9.2 继续语句

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

继续语句按如下方式执行:

· 如果 continue 语句退出一个或多个 try 块,则关联的最终块,控制权最初转移到最后阻止最里面的尝试语句。何时以及是否控制到达最终块的终点,控制权转移到下一个封闭的 try 语句的最后一个块。这个过程是重复直到所有干预 try 语句的最终块已被执行。

相关内容

  • 没有找到相关文章

最新更新