Why does this "finally" execute? - c#

If you run the code below it actually executes the finally after every call to the goto:
int i = 0;
Found:
i++;
try
{
throw new Exception();
}
catch (Exception)
{
goto Found;
}
finally
{
Console.Write("{0}\t", i);
}
Why?

The following text comes from the C# Language Specification (8.9.3 The goto statement)
A goto statement is executed as follows:
If the goto 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.
Control is transferred to the target of the goto statement.

Why do you expect it to not execute?
If you have try/catch/finally or try/finally block, finally block executes no matter what code you may have in the try or catch block most of the time.
Instead of goto, consider 'return'.
//imagine this try/catch/finally block is inside a function with return type of bool.
try
{
throw new Exception();
}
catch (Exception)
{
return false; //Let's say you put a return here, finally block still executes.
}
finally
{
Console.WriteLine("I am in finally!");
}

The gist of the answers given - that when control leaves the protected region via any means, whether "return", "goto", "break", "continue" or "throw", the "finally" is executed - is correct. However, I note that almost every answer says something like "the finally block always runs". The finally block does NOT always run. There are many situations in which the finally block does not run.
Who wants to try to list them all?

Seems reasonable. A finally block is always run after either the try or the catch.
Similarly
try
{
// do something
return;
}
finally
{
// do something else
}
will always run the finally block. EDIT - but see Eric's comments above.

That's by design. In the exception handler you can take some exception-specific action. In the finally block you should do resource cleanup - that's why the finally block is always executed no matter what the exception handling code is.

As people have mentioned, finally runs no matter the program flow. Of course, the finally block is optional, so if you don't need it, don't use it.

Because a finally statement is expected to execute after leaving the try (or catch when an exception is caught). This includes when you make your goto call.

That is the point of the finally block. It always executes (pretty much).

Related

Execution order of try, catch and finally block

Suppose I have some C# code like this:
try {
Method1();
}
catch(...) {
Method2();
}
finally {
Method3();
}
Method4();
return;
My question is, provided no exception is thrown, will Method3() be executed before Method4(), or is it that the finally block is only executed before a return, continue or break statement?
Yes, the finally block of the try-catch will be executed in order as you would expect, and then execution will proceed onto the rest of the code (after completing the entire try-catch-finally block).
You can think of the entire try-catch-finally block as a single component that would function just like any other method call would (with code being executed before and after it).
// Execute some code here
// try-catch-finally (the try and finally blocks will always be executed
// and the catch will only execute if an exception occurs in the try)
// Continue executing some code here (assuming no previous return statements)
Example
try
{
Console.WriteLine("1");
throw new Exception();
}
catch(Exception)
{
Console.WriteLine("2");
}
finally
{
Console.WriteLine("3");
}
Console.WriteLine("4");
return;
You can see an example of this in action here that yields the following output :
1
2
3
4
The sequence will always be
try
--> catch(if any exception occurs)
--> finally (in any case)
--> rest of the code (unless the code returns or if there is any uncaught exceptions from any of the earlier statements)
Useful resource: https://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx
My question is, provided no exception is thrown, will Method3() be executed before Method4(),
Yes, Method3 will be executed before Method4 because whether an exception is thrown or not, the execution will go to the finally block and then proceed from there.
or is it that the finally block is only executed before a return, continue or break statement?
No, it is always executed after the try block, whether there was an exception or not.
Important Point
If you have this:
try
{
DoOne();
DoTwo();
DoThree();
}
catch{ // code}
finally{ // code}
If an exception is thrown by DoOne() then DoTwo() and DoThree() will never be called. Therefore, do NOT think that the entire try block will always be executed. Actually, only the part until the exception is thrown will be executed and then execution goes to the catch block.
Finally will be executed always-despite whether there was an exception.

Can I get some clarification on the try catch finally concept? (C#) [duplicate]

In a Try Catch Finally block, does the finally block always execute no matter what, or only if the catch block does not return an error?
I was under the impression that the finally block only executes if the catch block passes without errors. If the catch block is executed because of an error, shouldn't it stop execution all together and return the error message if any?
The finally block (nearly) always executes, whether or not there was an exception.
I say nearly because there are a few cases where finally isn't guaranteed to be called:
If there is an infinite loop or deadlock in your code so that the execution remains inside the try or catch blocks then the finally block will never execute.
If your application is terminated abruptly by killing the process.
Power cut.
Calling Environment.FailFast.
Some exceptions such as:
StackOverflowException
OutOfMemoryException
ExecutingEngineException (now obsolete)
An exception thrown in a finalizer (source).
Furthermore, even if the finally block is entered if a ThreadAbortException occurs just as the thread enters the finally block the code in the finally block will not be run.
There may be some other cases too...
Not only will a finally block execute following a catch block, try does not even require that any exception be caught for the finally to execute. The following is perfectly legal code:
try
{
//do stuff
}
finally
{
//clean up
}
I actually took out the catch blocks in some code I inherited when the catch block consisted of:
catch(Exception ex)
{
throw ex;
}
In that case, all that was required was to clean up, so I left it with just a try{} and finally{} block and let exceptions bubble up with their stack trace intact.
the finally block executes in almost every case. That's why it's called 'finally'.
For an example, see this article on c-sharpcorner.com.
Update: It's true, if you plug the cable, melt the processor or grind the motherboard, even the most final 'finally' will not be executed.
But in almost every 'normal' scenario, i.e. wether your code throws an exception or not, the finally block will be executed. To my knowledge the only 'real' exception to this rule is a stackoverflow exception which will terminate the program w/o entering finally.
Update 2: This question was asked specifically for C#. This answer is NOT covering Java, Python, Matlab or Scheme.
The finally block will execute, but you'll need to be careful of exceptions within the finally block.
try {
// some disposable method "o"
} finally {
o.Dispose(); // if o is null, exception is thrown
// anything after this exception will fail to execute
}
The code inside the finally block gets always executed, regadless if there was an exception. By the way, I think there are already numerous threads on SO that deal with this question.

Why can't a 'continue' statement be inside a 'finally' block?

I don't have a problem; I'm just curious. Imagine the following scenario:
foreach (var foo in list)
{
try
{
//Some code
}
catch (Exception)
{
//Some more code
}
finally
{
continue;
}
}
This won't compile, as it raises compiler error CS0157:
Control cannot leave the body of a finally clause
Why?
finally blocks run whether an exception is thrown or not. If an exception is thrown, what the heck would continue do? You cannot continue execution of the loop, because an uncaught exception will transfer control to another function.
Even if no exception is thrown, finally will run when other control transfer statements inside the try/catch block run, like a return, for example, which brings the same problem.
In short, with the semantics of finally it doesn't make sense to allow transferring control from inside a finally block to the outside of it.
Supporting this with some alternative semantics would be more confusing than helpful, since there are simple workarounds that make the intended behaviour way clearer. So you get an error, and are forced to think properly about your problem. It's the general "throw you into the pit of success" idea that goes on in C#.
If you want to ignore exceptions (more often than not is a bad idea) and continue executing the loop, use a catch all block:
foreach ( var in list )
{
try{
//some code
}catch{
continue;
}
}
If you want to continue only when no uncaught exceptions are thrown, just put continue outside the try-block.
Here is a reliable source:
A continue statement cannot exit a finally block (Section 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.
It is taken from MSDN, 8.9.2 The continue statement.
The documentation say that:
The statements of a finally block are always executed when control leaves a
try statement. This is true whether the control transfer occurs as a
result of normal execution, as a result of executing a break,
continue, goto, or return statement, or as a result of propagating an
exception out of the try statement. If an exception is thrown during
execution of a finally block, the exception is propagated to the next
enclosing try statement. If another exception was in the process of
being propagated, that exception is lost. The process of propagating
an exception is discussed further in the description of the throw statement (Section 8.9.5).
It is from here 8.10 The try statement.
You may think it makes sense, but it doesn't make sense actually.
foreach (var v in List)
{
try
{
//Some code
}
catch (Exception)
{
//Some more code
break; or return;
}
finally
{
continue;
}
}
What do you intend to do a break or a continue when an exception is thrown? The C# compiler team doesn't want to make decision on their own by assuming break or continue. Instead, they decided to complain the developer situation will be ambiguous to transfer control from finally block.
So it is the job of developer to clearly state what he intends to do rather than compiler assuming something else.
I hope you understand why this doesn't compile!
As others have stated, but focused on exceptions, it's really about ambiguous handling of transferring control.
In your mind, you're probably thinking of a scenario like this:
public static object SafeMethod()
{
foreach(var item in list)
{
try
{
try
{
//do something that won't transfer control outside
}
catch
{
//catch everything to not throw exceptions
}
}
finally
{
if (someCondition)
//no exception will be thrown,
//so theoretically this could work
continue;
}
}
return someValue;
}
Theoretically, you can track the control flow and say, yes, this is "ok". No exception is thrown, no control is transferred. But the C# language designers had other issues in mind.
The Thrown Exception
public static void Exception()
{
try
{
foreach(var item in list)
{
try
{
throw new Exception("What now?");
}
finally
{
continue;
}
}
}
catch
{
//do I get hit?
}
}
The Dreaded Goto
public static void Goto()
{
foreach(var item in list)
{
try
{
goto pigsfly;
}
finally
{
continue;
}
}
pigsfly:
}
The Return
public static object ReturnSomething()
{
foreach(var item in list)
{
try
{
return item;
}
finally
{
continue;
}
}
}
The Breakup
public static void Break()
{
foreach(var item in list)
{
try
{
break;
}
finally
{
continue;
}
}
}
So in conclusion, yes, while there is a slight possibility of using a continue in situations where control isn't being transferred, but a good deal (majority?) of cases involve exceptions or return blocks. The language designers felt this would be too ambiguous and (likely) impossible to ensure at compile time that your continue is used only in cases where control flow is not being transferred.
In general continue does not make sense when used in finally block. Take a look at this:
foreach (var item in list)
{
try
{
throw new Exception();
}
finally{
//doesn't make sense as we are after exception
continue;
}
}
"This won't compile and I think it makes complete sense"
Well, I think it doesn't.
When you literally have catch(Exception) then you don't need the finally (and probably not even the continue).
When you have the more realistic catch(SomeException), what should happen when an exception is not caught? Your continue wants to go one way, the exception handling another.
You cannot leave the body of a finally block. This includes break, return and in your case continue keywords.
The finally block can be executed with an exception waiting to be rethrown. It wouldn't really make sense to be able to exit the block (by a continue or anything else) without rethrowing the exception.
If you want to continue your loop whatever happens, you do not need the finally statement: Just catch the exception and don't rethrow.
finally runs whether or not an uncaught exception is thrown. Others have already explained why this makes continue illogical, but here is an alternative that follows the spirit of what this code appears to be asking for. Basically, finally { continue; } is saying:
When there are caught exceptions, continue
When there are uncaught exceptions, allow them to be thrown, but still continue
(1) could be satisfied by placing continue at the end of each catch, and (2) could be satisfied by storing uncaught exceptions to be thrown later. You could write it like this:
var exceptions = new List<Exception>();
foreach (var foo in list) {
try {
// some code
} catch (InvalidOperationException ex) {
// handle specific exception
continue;
} catch (Exception ex) {
exceptions.Add(ex);
continue;
}
// some more code
}
if (exceptions.Any()) {
throw new AggregateException(exceptions);
}
Actually, finally would have also executed in the third case, where there were no exceptions thrown at all, caught or uncaught. If that was desired, you could of course just place a single continue after the try-catch block instead of inside each catch.
Technically speaking, it's a limitation of the underlying CIL. From the language spec:
Control transfer is never permitted to enter a catch handler or finally clause except through the exception handling mechanism.
and
Control transfer out of a protected region is only permitted through an exception instruction (leave, end.filter, end.catch, or end.finally)
On the doc page for the br instruction:
Control transfers into and out of try, catch, filter, and finally blocks cannot be performed by this instruction.
This last holds true for all branch instructions, including beq, brfalse, etc.
The designers of the language simply didn't want to (or couldn't) reason about the semantics of a finally block being terminated by a control transfer.
One issue, or perhaps the key issue, is that the finally block gets executed as part of some non-local control transfer (exception processing). The target of that control transfer isn't the enclosing loop; the exception processing aborts the loop and continues unwinding further.
If we have a control transfer out of the finally cleanup block, then the original control transfer is being "hijacked". It gets canceled, and control goes elsewhere.
The semantics can be worked out. Other languages have it.
The designers of C# decided to simply disallow static, "goto-like" control transfers, thereby simplifying things somewhat.
However, even if you do that, it doesn't solve the question of what happens if a dynamic transfer is initiated from a finally: what if the finally block calls a function, and that function throws? The original exception processing is then "hijacked".
If you work out the semantics of this second form of hijacking, there is no reason to banish the first type. They are really the same thing: a control transfer is a control transfer, whether it the same lexical scope or not.

Does code in a finally get executed if I have a return in my catch() in c#?

I have the following code snippet / example. It's not working code I just wrote this so as to ask a question about catch, finally and return:
try
{
doSomething();
}
catch (Exception e)
{
log(e);
return Content("There was an exception");
}
finally
{
Stopwatch.Stop();
}
if (vm.Detail.Any())
{
return PartialView("QuestionDetails", vm);
}
else
{
return Content("No records found");
}
From what I understand if there's an exception in the try block it will go to catch. However if there is a return statement in the catch then will the finally be executed? Is this the correct way to code a catch and finally ?
Within a handled exception, the associated finally block is guaranteed
to be run. However, if the exception is unhandled, execution of the
finally block is dependent on how the exception unwind operation is
triggered. That, in turn, is dependent on how your computer is set up.
For more information, see Unhandled Exception Processing in the CLR.
Ref: Try-Finally
Yes the finally will get executed, even if you return something before.
The finally block is useful for cleaning up any resources that are allocated in the try block, and for running any code that must execute even if an exception occurs in the try block. Typically, the statements of a finally block are executed when control leaves a try statement, whether the transfer of control occurs as a result of normal execution, of execution of a break, continue, goto, or return statement, or of propagation of an exception out of the try statement.
More Information
MSDN - try-finally (C# Reference)
The finally will be executed even if there is a return within the catch block
finally block is always executed
The finally will execute after the catch-block is exited (in your by means of an explicit "return"). However, everything after the finally-block (in your case the if (vm.Detail.Any()) ...) will not execute.
The code in the finally block will run despite the return statement in your catch block.
However, I personally would assign the result to a variable and return it after the block.
But that's just a matter of taste.

If I return out of a try/finally block in C# does the code in the finally always run?

It seems like it does as per some initial testing, but what I'd like to know is if it is guaranteed to return or if in some cases it can not return? This is critical for my application but I haven't found a use-case yet where it wouldn't return.
I'd like to get expertise on the subject.
There are a number of inaccuracies in the other answers.
Control is passed to the finally block when control leaves the try block normally -- that is, by a return, goto, break, continue, or simply falling off the end. Control is passed to the finally block when control leaves the try block via an exception that has been caught by an enclosing catch block.
In every other circumstance there is no guarantee that the code in the finally block will be called. In particular:
If the try block code goes into an infinite loop, or the thread is frozen and never unfrozen, then the finally block code is never called.
If the process is paused in the debugger and then aggressively killed then the finally block is never called. If the process does a fail-fast then the finally block is never called.
If the power cord is pulled out of the wall then the finally block is never called.
If there is an exception thrown without a corresponding catch block then whether the finally block runs or not is an implementation detail of the runtime. The runtime can choose any behaviour when there is an uncaught exception. Both "do not run the finally blocks" and "do run the finally blocks" are examples of "any behaviour", so either can be chosen. Typically what the runtime does is ask the user if they want to attach a debugger before the finally blocks run; if the user says no then the finally blocks run. But again: the runtime is not required to do that. It could just fail fast.
You cannot rely on finally blocks always being called. If you require a strong guarantee about code executing then you should not be writing a try-finally, you should be writing a constrained execution region. Writing a CER correctly is one of the most difficult tasks in C# programming, so study the documentation carefully before you try to write the code.
Incidentally, a "fun fact" about finally-blocked gotos is:
try { goto X; } finally { throw y; }
X : Console.WriteLine("X");
X is an unreachable label targetted by a reachable goto! So next time you're at a party you can be like "hey everybody, can anyone make a C# program that has an unreachable label that is targetted by a reachable goto?" and you'll see who at the party has read the reachability specification and who has not!
Under normal conditions, code in a finally block will be executed regardless of what happens inside the try or catch blocks. It doesn't matter if you return from the method or not.
There are cases where this is not true. For example if the code in the finally block throws an exception, then it will stop executing like any other block of code.
Eric Lippert has written a much more comprehensive answer that outlines additional cases: https://stackoverflow.com/a/10260233/53777
In regards to goto, the answer is still yes. Consider the following code:
try
{
Console.WriteLine("Inside the Try");
goto MyLabel;
}
finally
{
Console.WriteLine("Inside the Finally");
}
MyLabel:
Console.WriteLine("After the Label");
The output produced is this:
Inside the Try
Inside the Finally
After the Label
Here are some examples:
Environment.FailFast()
try
{
Console.WriteLine("Try");
Environment.FailFast("Test Fail");
}
catch (Exception)
{
Console.WriteLine("catch");
}
finally
{
Console.WriteLine("finally");
}
The output is only "Try"
Stackoverflow
try
{
Console.WriteLine("Try");
Rec();
}
catch (Exception)
{
Console.WriteLine("catch");
}
finally
{
Console.WriteLine("finally");
}
Where Rec is:
private static void Rec()
{
Rec();
}
The output is only "Try" and the process terminates due to StackOverflow.
Unhanded exception
try
{
Console.WriteLine("Try");
throw new Exception();
}
finally
{
Console.WriteLine("finally");
}
In case of fatal exceptions that terminate application Finally block will not be called. Includes stack overflow, exceptions during JIT of methods to call, fatal exceptions insisde CLR runtime.
As #mintech points out if application hangs inside the block it simply will not reach finally block. This includes waiting for synchronization objects, deadlocks infinite loops or even UI that does not have a way to close it.

Categories