Nested try-finally in C# - c#

Why isn't the line "Console.WriteLine("asdf");" executed? All the others are. Shouldn't it also be as we can't jump out from the finally scope?
static bool Func()
{
try
{
try
{
}
finally
{
try
{
throw new ApplicationException();
}
finally
{
Console.WriteLine("asd");
}
Console.WriteLine("asdf");
}
}
finally
{
Console.WriteLine("asd");
}
}

Finally blocks only guarantee (at least mostly guarantee, see excerpt from MSDN below) that they will be entered in the event that the try block throws an exception. If you throw an exception within the finally block, the exception will cause control to leave the finally block and the rest of the code within that finally block will not execute.
In your case, the line that isn't being executed is occurring after an exception in the same finally block, so it gets skipped.
From MSDN - try-finally:
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.
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.
Note: Unhandled Exception Processing in the CLR is a reference to an article in the September 2008 issue of the MSDN Magazine. All 2008 and older issues of MSDN Magazine are only available as .chm files, and will need to be downloaded before viewing.

I think the best way this could be answered is by using the code and hence the following image

Because the exception is being thrown in that finally block, so it causes control to fall out to the final finally block. So the "asdf" WriteLine never executes.

Exceptions thrown within a finally(or catch) block cancel the remainder of that finally(or catch) block.

The error occurs inside the 3rd try block which causes its corresponding finally to be executed. However, this causes it to error out of the current finally and be caught by the original try-finally block.

because you have throw in try block and it will execute finally block with Console.WriteLine("asd"); and exit to outer try catch

When I used try-finally blocks on code deployed across different host platorms I found that:
when no exceptions were thrown on the try block.
some Windows platforms always executed the finally block and
some platforms never executed the finally block.
My finally block contained instructions to close down the error log and failure to execute the finally block always raised another exception on exit leaving only cryptric innformation available to find out what caused the error.
For my application try finally blocks were more trouble than they were worth.

Related

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.

in C# is it possible to force control to pass through a finally block if an exception is thrown by an associated catch block?

I know that in Java, if an exception is caught by a catch clause and its catch block throws an exception, control would pass throw the associated finally block (if any) before the thread is terminated. This does not appear to be the case in C#, however.
It is possible to almost mirror this behavior in C# is by putting a try-finally statement inside the try block of the try-catch statement with the catch block that throws the exception, but that would be a problem if, for example, the finally block is supposed to contain code that disposes a Stream Writer that is supposed to log the exception.
Is there a clean way to achieve java-like try-catch-finally exception handling behavior in C#?
Here's an update with the requested sample code:
StreamWriter writer = new StreamWriter("C:\\log.txt");
try
{
throw new Exception();
}
catch (Exception e)
{
writer.WriteLine(e.Message);
throw e;
}
finally
{
if (writer != null)
{
writer.Dispose();
}
}
Add that code to a console application, run it, let the re-thrown exception go unhandled, attempt to delete C:\log.txt. You won't be able to, because control never passed through the finally block. Also, if you add a breakpoint to some line inside the finally block you will see that it doesn't get hit. (I'm using VS2005).
As far as I know, the only way to force control to pass through the finally block is if the re-thrown exception is handled by the catch block of an enclosing try block (if you took the code above and placed it inside the try block of another try-catch statement).
If the exception is not caught and is allowed to terminate the application, as in the sample code I provided, control won't pass through the finally block.
In Java it would. In C#, at least based on what I have seen, it would not.
No, this is incorrect. C# will always execute the finally block, even after an exception is thrown/re-thrown from the catch block. See When is finally run if you throw an exception from the catch block?.
In the .NET Framework, when an exception occurs, the system will determine what if anything is going to catch that exception before any finally blocks execute. Depending upon various application settings, an attempt to throw an exception which will not be caught may kill the application instantly, without giving any finally blocks (or anything else) a chance to run.
If one wraps the Main method, as well as each thread, in
try
{
...
}
catch
{
throw;
}
then any exception which is thrown within the try block will get caught. Even though it will be immediately re-thrown, any nested finally blocks will execute before the catch. There are some cases where this is desirable behavior; there are other cases where one may wish to e.g. perform some special logging if an exception isn't going to be caught (in some cases, the information one wishes to log may be destroyed if the finally blocks get a chance to run first). Within C#, there isn't any way to vary one's actions based upon whether an exception is going to be caught, but in VB.NET there are some ways via which that can be done; a VB.NET assembly which makes calls to C# code can give that code a way of knowing whether any exceptions thrown by an inner method will propagate out to the vb.net wrapper without being caught.
This does not appear to be the case in C#, however.
Is this what you are looking for.
As already stated, the finally block will always run once the catch block has been executed.
Edit: I just tried the sample code provided by the OP in a console application and lo and behold, it did not hit the finally block and had an error of "An unhandled exception of type 'System.Exception' occurred in ConsoleApplication1.exe". This was truly puzzling (besides the part of re-throwing the same exception in an endless loop) so I did a little investimagation and this is what I found:
If a exception occurs the CLR traverses up the call stack looking for
a matching catch expression. If the CLR doen't finds a matching one,
or the Exception gets re thrown each time, the Exception bubbles out
of the Main() method. In that case Windows handles the Exception.
Event Handling of Console Applications is the easiest to understand,
because there is no special Handling by the CLR. The Exception is
leaving the Applications Thread if not caught. The CLR opens a window
asking for debug or exit the application. If the user chooses to
debug, the debugger starts. If the user chooses to close, the
Application exits and the Exception is serialized and written to the
console.
Moral of the story, do not re-throw the same exception from a catch block in a console application!.

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.

Will code in a Finally statement fire if I return a value in a Try block?

I'm reviewing some code for a friend and say that he was using a return statement inside of a try-finally block. Does the code in the Finally section still fire even though the rest of the try block doesn't?
Example:
public bool someMethod()
{
try
{
return true;
throw new Exception("test"); // doesn't seem to get executed
}
finally
{
//code in question
}
}
Simple answer: Yes.
Normally, yes. The finally section is guaranteed to execute whatever happens including exceptions or return statement. An exception to this rule is an asynchronous exception happening on the thread (OutOfMemoryException, StackOverflowException).
To learn more about async exceptions and reliable code in that situations, read about constrained execution regions.
Here's a little test:
class Class1
{
[STAThread]
static void Main(string[] args)
{
Console.WriteLine("before");
Console.WriteLine(test());
Console.WriteLine("after");
}
static string test()
{
try
{
return "return";
}
finally
{
Console.WriteLine("finally");
}
}
}
The result is:
before
finally
return
after
Quoting from MSDN
finally is used to guarantee a statement block of code executes regardless of how the preceding try block is exited.
Generally yes, the finally will run.
For the following three scenarios, the finally will ALWAYS run:
No exceptions occur
Synchronous exceptions (exceptions that occur in normal program flow).
This includes CLS compliant exceptions that derive from System.Exception and non-CLS compliant exceptions, which do not derive from System.Exception. Non-CLS compliant exceptions are automatically wrapped by the RuntimeWrappedException. C# cannot throw non-CLS complaint exceptions, but languages such as C++ can. C# could be calling into code written in a language that can throw non-CLS compliant exceptions.
Asynchronous ThreadAbortException
As of .NET 2.0, a ThreadAbortException will no longer prevent a finally from running. ThreadAbortException is now hoisted to before or after the finally. The finally will always run and will not be interrupted by a thread abort, so long as the try was actually entered before the thread abort occurred.
The following scenario, the finally will not run:
Asynchronous StackOverflowException.
As of .NET 2.0 a stack overflow will cause the process to terminate. The finally will not be run, unless a further constraint is applied to make the finally a CER (Constrained Execution Region). CERs should not be used in general user code. They should only be used where it is critical that clean-up code always run -- after all the process is shutting down on stack overflow anyway and all managed objects will therefore be cleaned-up by default. Thus, the only place a CER should be relevant is for resources that are allocated outside of the process, e.g., unmanaged handles.
Typically, unmanaged code is wrapped by some managed class before being consumed by user code. The managed wrapper class will typically make use of a SafeHandle to wrap the unmanaged handle. The SafeHandle implements a critical finalizer, and a Release method that is run in a CER to guarantee the execution of the clean-up code. For this reason, you should not see CERs littered through-out user code.
So the fact that the finally doesn't run on StackOverflowException should have no effect to user code, since the process will terminate anyway. If you have some edge case where you do need to clean-up some unmanaged resource, outside of a SafeHandle or CriticalFinalizerObject, then use a CER as follows; but please note, this is bad practice -- the unmanaged concept should be abstracted to a managed class(es) and appropriate SafeHandle(s) by design.
e.g.,
// No code can appear after this line, before the try
RuntimeHelpers.PrepareConstrainedRegions();
try
{
// This is *NOT* a CER
}
finally
{
// This is a CER; guaranteed to run, if the try was entered,
// even if a StackOverflowException occurs.
}
There's a very important exception to this which I haven't seen mentioned in any other answers, and which (after programming in C# for 18 years) I can't believe I didn't know.
If you throw or trigger an exception of any sort inside your catch block (not just weird StackOverflowExceptions and things of that ilk), and you don't have the entire try/catch/finally block inside another try/catch block, your finally block won't execute. This is easily demonstrated - and if I hadn't seen it myself, given how often I've read that it's only really weird, tiny corner-cases that can cause a finally block not to execute, I wouldn't have believed it.
static void Main(string[] args)
{
Console.WriteLine("Beginning demo of how finally clause doesn't get executed");
try
{
Console.WriteLine("Inside try but before exception.");
throw new Exception("Exception #1");
}
catch (Exception ex)
{
Console.WriteLine($"Inside catch for the exception '{ex.Message}' (before throwing another exception).");
throw;
}
finally
{
Console.WriteLine("This never gets executed, and that seems very, very wrong.");
}
Console.WriteLine("This never gets executed, but I wasn't expecting it to.");
Console.ReadLine();
}
I'm sure there's a reason for this, but it's bizarre that it's not more widely known. (It's noted here for instance, but not anywhere in this particular question.)
I realize I'm late to the party but in the scenario (differing from the OP's example) where indeed an exception is thrown MSDN states (https://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx): "If the exception is not caught, execution of the finally block depends on whether the operating system chooses to trigger an exception unwind operation."
The finally block is only guaranteed to execute if some other function (such as Main) further up the call stack catches the exception. This detail is usually not a problem because all run time environments (CLR and OS) C# programs run on free most resources a process owns when it exits (file handles etc.). In some cases it may be crucial though: A database operation half underway which you want to commit resp. unwind; or some remote connection which may not be closed automatically by the OS and then blocks a server.
Yes. That is in fact that main point of a finally statement. Unless something catestrophic occurs (out of memory, computer unplugged, etc.) the finally statement should always be executed.
It will also not fire on uncaught exception and running in a thread hosted in a Windows Service
Finally is not executed when in a Thread running in a Windows Service
finally wont run in case if you are exiting from the application using
System.exit(0); as in
try
{
System.out.println("try");
System.exit(0);
}
finally
{
System.out.println("finally");
}
the result would be just :
try
99% of the scenarios it will be guaranteed that the code inside the finally block will run, however, think of this scenario: You have a thread that has a try->finally block (no catch) and you get an unhandled exception within that thread. In this case, the thread will exit and its finally block will not be executed (the application can continue to run in this case)
This scenario is pretty rare, but it's only to show that the answer is not ALWAYS "Yes", it's most of the time "Yes" and sometimes, in rare conditions, "No".
The main purpose of finally block is to execute whatever is written inside it. It should not depend upon whatever happens in try or catch.However with System.Environment.Exit(1) the application will exit without moving to next line of code.

Categories