I've seen this example:
static void Main(string[] args) { Console.WriteLine("Start"); try { SomeOperation(); } catch (Exception) when (EvaluatesTo()) { Console.WriteLine("Catch"); } finally { Console.WriteLine("Outer Finally"); } } private static bool EvaluatesTo() { Console.WriteLine($"EvaluatesTo: {Flag}"); return true; } private static void SomeOperation() { try { Flag = true; throw new Exception("Boom"); } finally { Flag = false; Console.WriteLine("Inner Finally"); } }
Which produces the next output:
Start EvaluatesTo: True Inner Finally Catch Outer Finally
This sounds weird to me, and I'm looking for a good explanation of this order to wrap it up in my head. I was expecting the finally
block to be executed before when
:
Start Inner Finally EvaluatesTo: True Catch Outer Finally
The documentation states that this execution order is correct, but it does not elaborate on why it is done like that and what exactly are the rules of the execution order here.
A finally block is always get executed whether the exception has occurred or not. If an exception occurs like closing a file or DB connection, then the finally block is used to clean up the code. We cannot say the finally block is always executes because sometimes if any statement like System.
Yes, the finally block will be executed even after a return statement in a method. The finally block will always execute even an exception occurred or not in Java. If we call the System.
finally defines a block of code we use along with the try keyword. It defines code that's always run after the try and any catch block, before the method is completed. The finally block executes regardless of whether an exception is thrown or caught.
finally − The finally block is used to execute a given set of statements, whether an exception is thrown or not thrown. For example, if you open a file, it must be closed whether an exception is raised or not. throw − A program throws an exception when a problem shows up. This is done using a throw keyword.
You might have been taught that when exception handling occurs, every method is considered separately. That is, since your inner method has a try...finally
, any exception will first trigger the finally
, and then it will "look" for a try
higher up. This isn't true.
From the ECMA specification of CLR (ECMA-335, I.12.4.2.5 Overview of exception handling):
When an exception occurs, the CLI searches the array for the first protected block that
- Protects a region including the current instruction pointer and
- Is a catch handler block and
- Whose filter wishes to handle the exception
If a match is not found in the current method, the calling method is searched, and so on. If no match is found the CLI will dump a stack trace and abort the program.
If a match is found, the CLI walks the stack back to the point just located, but this time calling the finally and fault handlers. It then starts the corresponding exception handler.
As you can see, the behaviour is 100% compliant with the specification.
try
in SomeOperation
try
in Main
finally
in SomeOperation
The finally
in Main
isn't part of this, of course - it will execute when execution leaves the protected block, regardless of the exception.
EDIT:
Just for completeness - this has always been this way. The only thing that changed is that C# now supports exception filters, which allows you to observe the order of execution. VB.NET supported exception filters from version 1.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With