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.
Related
This question already has answers here:
When is finally run if you throw an exception from the catch block?
(8 answers)
Closed 5 years ago.
I wrote simple C# console app:
class Mystery
{
static void Main(string[] args)
{
MakeMess();
}
private static void MakeMess()
{
try
{
System.Console.WriteLine("try");
throw new Exception(); // let's invoke catch
}
catch(Exception)
{
System.Console.WriteLine("catch");
throw new Exception("A");
}
finally
{
System.Console.WriteLine("finally");
throw new Exception("B");
}
}
}
The output given in console is:
try
catch
Unhandled Exception: System.Exception: A at Mystery.Program.MakeMess() in ...
It seems that CLR caught A and the finally block was not invoked at all.
But when I surround call to MakeMess() with try-catch block:
static void Main(string[] args)
{
try
{
MakeMess();
}
catch(Exception ex)
{
System.Console.WriteLine("Main caught " + ex.Message);
}
}
The output looks totally different:
try
catch
finally
Main caught B
It seems that Exception that propagates from MakeMess() is different when Exception is strictly handled outside of method.
What's the explanation of this behavior?
The behavior you are seeing has nothing to do with a finally block throwing or not. You simply have an unhandled exception in your application, when that happens, all bets are off, including if finally blocks run or not:
From MSDN documentation:
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.
Usually, when an unhandled exception ends an application, whether or not the finally block is run is not important. However, if you have statements in a finally block that must be run even in that situation, one solution is to add a catch block to the try-finally statement. Alternatively, you can catch the exception that might be thrown in the try block of a try-finally statement higher up the call stack. That is, you can catch the exception in the method that calls the method that contains the try-finally statement, or in the method that calls that method, or in any method in the call stack. If the exception is not caught, execution of the finally block depends on whether the operating system chooses to trigger an exception unwind operation.
If the finally block must run, then the solution is to do precisely what you've done in the second snippet: handle the unhandled exception.
What happens if a finally block throws an exception? :
C# 4 Language Specification ยง 8.9.5: If the finally block throws another exception, processing of the current exception is terminated.
I think that finally block is for cleanig resources only and should not throw any exceptions.
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.
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.
When I use try, catch blocks, if any exception is throws the program execution is stopped after the catch is handled. But, I need to continue the program execution even if there is exception. Can any one help me how to do it?
If I understand correctly, here's what you're wanting:
try
{
Statement1(); // <-- Exception is thrown in here
Statement2(); // <-- You want to go here after the catch block executes
}
catch
{
HandleException();
}
Try/catch blocks don't work that way. You would have to rewrite your code as follows, instead:
try
{
Statement1();
}
catch
{
}
try
{
Statement2();
}
catch
{
}
Uncaught exceptions terminate execution.
If an exception is caught and not rethrown, the catch() clause is executed, then the finally() clause (if there is one) and execution then continues with the statement following the try/catch/finally block.
If an exception is caught and rethrown, the catch() clause is executed up to and including the throw statement; the finally() clause (if there is one) is executed), then exception is (re-)thrown and the stack unwinding continues.
As the call stack is unwound, finally() clauses are executed as they go out of scope and Dispose() is called as variables declare in using statements go out of scope.
What does not happen is that control does not (and cannot) resume at the point the original exception was thrown. It sounds like you are catching exceptions at a high level -- such as your Main() method -- and expecting execution to continue at original point of failure.
To make that happen, you need to catch the exception at the point at which handling makes contextual sense, and, having handled the exception, either retry the failing operation or ignore the problem.
Doing exception handling well is rather difficult; hence the dictum that the best exception handling practice is to not handle it. Exceptions are supposed to be just that: exceptional. Your code should not throw exception as a normal matter of course; nor should you generally use exceptions as validation technique or as a flow-of-control operator.
If you handle the exception and do not re-throw it (or another Exception) from your catch block, your program should resume.
Additionally, if you are catching exceptions of a certain type (say IO exceptions), but the code in the try block is throwing a different type (say a SQL exception), your catch block with not catch it and the exception will bubble up till the program terminates.
What exactly are you doing in your catch blocks?
If you talking about function (not program) you can use finally to continue your function
try
{
}
catch(MyException ex)
{
}
finally
{
// other code to be done
}
but if you saying program crashes, the cach without any argument can handle it.
If you've reached out to a method that contains your try and catch, you could just do something like this...
//Start Here
exceptionMethod()
//Code will continue here after you've returned from your catch block in exceptionMethod()
doSomeMoreStuff()
exceptionMethod()
try{
doStuff()
}
catch(Exception e){
return
}
a simple return in your catch block should do the trick.
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).