简体   繁体   English

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

[英]When does a finally block execute if the catch block contains a continue statement?

I have some code that looks like this:我有一些代码看起来像这样:

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);
      }
   }
}

The objective is to try and write out a temporary file for each object in the collection, attempt to load that file into an external API which wants filenames, and then clean up the temporary files when done.目标是尝试为集合中的每个对象写出一个临时文件,尝试将该文件加载到需要文件名的外部 API 中,然后在完成后清理临时文件。 If an error happens when writing the file out to disk or loading it to the external API, I just want to log the error and move on to the next object;如果在将文件写入磁盘或将其加载到外部 API 时发生错误,我只想记录错误并继续处理下一个对象; I can't ask the user what to do.我不能问用户要做什么。

I'm a bit uncertain of how the timing of finally blocks work when you have continue statements in the catch handlers.当您在 catch 处理程序中有 continue 语句时,我有点不确定 finally 块的时间如何工作。 Is this code going to (attempt to) delete the correct file no matter whether an exception is thrown in the try block?无论 try 块中是否抛出异常,这段代码是否都会(尝试)删除正确的文件 Or do the continues in the catch statements take effect before the finally block runs?还是在 finally 块运行之前 catch 语句中的 continues 生效?

Think of it as a try/finally block with catch expressions optional.将其视为带有可选的 catch 表达式的 try/finally 块。 Both continue statements in your code would pop the execution stack out of the catch which would place execution in the finally block before allowing the loop to continue.代码中的两个 continue 语句都会将执行堆栈从 catch 中弹出,这会在允许循环继续之前将执行置于 finally 块中。 Any time there is a try/finally block, finally will always be executed.任何时候有 try/finally 块,finally 总是会被执行。

Your finally block will be executed irrespective of whether the exception is thrown or not.无论是否抛出异常,您的 finally 块都将被执行。 So your finally block will be always executed.所以你的 finally 块将始终被执行。

The finally will execute as the last step before the try finishes. finally将作为try完成前的最后一步执行。 Therefore it will occur at the right time.因此它会在正确的时间发生。 To make it easier to conceptualize, think about what would happen if all of the continue statements were replaced by return - the finally would still execute.为了更容易概念化,想想如果所有的continue语句都被return替换会发生什么finally仍然会执行。

From the C# Language Specification :来自C# Language Specification

8.9.2 The continue statement 8.9.2 continue 语句

... ...

A continue statement cannot exit a finally block (§8.10). continue 语句不能退出 finally 块(§8.10)。 When a continue statement occurs within a finally block, the target of the continue statement must be within the same finally block;当 finally 块中出现 continue 语句时,continue 语句的目标必须在同一个 finally 块中; otherwise a compile-time error occurs.否则会发生编译时错误。

A continue statement is executed as follows: continue 语句执行如下:

· If the continue statement exits one or more try blocks with associated finally blocks, control is initially transferred to the finally block of the innermost try statement. · 如果 continue 语句退出一个或多个与 finally 块相关联的 try 块,则控制最初转移到最内层 try 语句的 finally 块。 When and if control reaches the end point of a finally block, control is transferred to the finally block of the next enclosing try statement.当控制到达 finally 块的结束点时,控制将转移到下一个封闭 try 语句的 finally 块。 This process is repeated until the finally blocks of all intervening try statements have been executed.重复此过程,直到执行完所有中间 try 语句的 finally 块。

... ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM