Reputation: 3806
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
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
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
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
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