Hydrargyrum
Hydrargyrum

Reputation: 3806

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. 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; 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. Is this code going to (attempt to) delete the correct file no matter whether an exception is thrown in the try block? Or do the continues in the catch statements take effect before the finally block runs?

Upvotes: 7

Views: 5285

Answers (4)

Mark Hall
Mark Hall

Reputation: 54532

From the C# Language Specification:

8.9.2 The continue statement

...

A continue statement cannot exit a finally block (§8.10). When a continue statement occurs within a finally block, the target of the continue statement must be within the same finally block; otherwise a compile-time error occurs.

A continue statement is executed as follows:

· 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. 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. This process is repeated until the finally blocks of all intervening try statements have been executed.

...

Upvotes: 8

EdFred
EdFred

Reputation: 711

Think of it as a try/finally block with catch expressions optional. 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. Any time there is a try/finally block, finally will always be executed.

Upvotes: 20

Michael
Michael

Reputation: 9044

The finally will execute as the last step before the try finishes. 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.

Upvotes: 8

Sudhakar B
Sudhakar B

Reputation: 1563

Your finally block will be executed irrespective of whether the exception is thrown or not. So your finally block will be always executed.

Upvotes: 11

Related Questions