Why finally?

K

Ken

What is the purpose of a finally block in try-catch-
finally? I am confused because, if I am reading the
definition correctly, this block seems unnecessary.
Consider the following from the Visual Studio
documentation. In the first foo(), the statement in the
finally block will execute even though there is an
exception in the try block. In the second foo(), I took
the statement out of the finally block but it should still
execute since it comes after the whole thing.

So... what is the difference between a "finally" block and
nothing at all?

void foo()
{
int i = 123;
string s = "Some string";
object o = s;

try
{
// Invalid conversion; o contains a string not an int
i = (int) o;
}
catch (Exception e)
{
Console.WriteLine("Exception!");
}
finally
{
Console.Write("i = {0}", i);
}
}

Now, consider something similar:

void foo()
{
int i = 123;
string s = "Some string";
object o = s;

try
{
// Invalid conversion; o contains a string not an int
i = (int) o;
}
catch (Exception e)
{
Console.WriteLine("Exception!");
}

Console.Write("i = {0}", i);
}
 
J

Jon Skeet

Ken said:
What is the purpose of a finally block in try-catch-
finally? I am confused because, if I am reading the
definition correctly, this block seems unnecessary.
Consider the following from the Visual Studio
documentation. In the first foo(), the statement in the
finally block will execute even though there is an
exception in the try block. In the second foo(), I took
the statement out of the finally block but it should still
execute since it comes after the whole thing.

So... what is the difference between a "finally" block and
nothing at all?

The difference is when an exception *isn't* caught, but is propagated
up the stack, or when the catch block terminates the method (returns or
throws an exception itself). This doesn't happen in your case, because
you're catching Exception (well, I suppose it will happen if some non-
CLS compliant exception, or an uncatchable exception, is thrown).
 
E

EMonaco

Ken,

Having a finally block ensures that the code inside of it will always be
executed before the function is exited.

example:

try
{
// Invalid conversion; o contains a string not an int
i = (int) o;
// if you do not have an exception return
return; // normally this would exit the function, however because
finally{} that code will be executed as well.
}
catch (Exception e)
{
Console.WriteLine("Exception!");
throw e; // this would cause function exit too- with finally{} that
code will be executed!
}
finally
{
Console.Write("i = {0}", i);
}
}

finally{} is a great place to put resource clean up code- ensuring that it
always gets executed before returning!
Examples are things such as .Close() of streams, messaging, signalling, etc.
As most importantly, if you work with critical sections, mutex's etc. You
should put that release of those objects in a finally{} to ensure that they
are released so you don't encounter a deadlock, or resource indefinitely
locked issues.


Erin.
 
J

Jay B. Harlow [MVP - Outlook]

Ken,
Consider the following:
try
{
// Invalid conversion; o contains a string not an int
i = (int) o;
} catch (ApplicationException e)
{
Console.WriteLine("Exception!");
}
finally
{
Console.Write("i = {0}", i);
}

Where I only want to catch ApplicationExceptions, other kind of exceptions
will be handled outside of this routine.

For any kind of exception Application or otherwise I want the finally to be
executed.

Also finally is useful if you want to catch the exception, log it, then
rethrow the exception so others can deal with it.

catch (Exception ex)
{
ExceptionHandler(ex); // logs the exception
throw; // (re) throws the caught exception
}
finally
{
// do clean up here
}

Hope this helps
Jay
 
A

Andre

Lots of reasons.. imagine you have a number of Catch()'s.. different
ones that catch different type of exceptions. One that catches an
IOException and one that catches a MalNumberformat or whatever. Suppose
the MalNumberFormat exception might occur at the very start of the
method and the IOException might occur near the end of the method. Also
suppose that you already have a file opened or a scarse resource in use
*before* the line where a NumberFormat exception can be thrown. Now if
your program at runtime encounters a NumberFormat exception, you might
end up with that scarce resource un-closed because it wasn't normally
closed after being used after the lines in the method that make use of
it (which are near the end of the method). Now also suppose that the
Catch(NumberFormatException) block deals with this problem a little
differently, in that, it 'retries' the method by jumping over to a label
in the method to the line where the exception was thrown, just to give
it another try... it would then not be wise to close the file in this
catch block. Similarly, after triend a couple of times, you might want
to jump off to another part of the code in the catch block and might not
ever release the file or the resource. 'finally' gives you the
assurances that the peice of code inside 'finally' will always be called
and so you can safely release your resources and close them 'properly'
in whatever manner you wish. Finally has a number of other similar uses.
Hope that clears a bit...


-Andre
 
T

tribal

When an error is generated the runtime checks to see if
there is a finally block and if one is found then it is
executed. Any other code after finally will not be reached
as an error was generated and it is to be dealt with

The finally block is executed even if there is no error
This is helpful for code cleanup example to close file
references etc.. as it is always guaranteed to be executed


hope this helps

regards

tribal
 
K

Ken

Thanks! This is the difference I was looking for. The
documentation did not make it clear to me that a finally
block was executed even if the "catch" block exited the
function. Now I can clearly see their benefit.
 
J

Jon Skeet

james said:
Jon, you cannot return from a try catch finally block. You will get an
error

You can't return from a finally block, but you can most definitely
return from try and catch blocks:

using System;

public class Test
{

static void Main()
{
string x = ReturnFromTry();
Console.WriteLine (x);
x = ReturnFromCatch();
Console.WriteLine (x);
}

static string ReturnFromTry()
{
try
{
return "try";
}
catch
{
}
finally
{
Console.WriteLine ("Finally");
}
return "Oops";
}

static string ReturnFromCatch()
{
try
{
throw new Exception();
}
catch
{
return "catch";
}
finally
{
Console.WriteLine ("Finally");
}
}
}
 
J

Jon Skeet

james said:
Yep, I guess I misread, I was thinking of return from finally.
Which by the way is kind of a pain not being able to do that.

Indeed. It would often be a mistake to do it, but it's occasionally
handy. (You can do it in Java, which is how I know it's handy sometimes
:)
 
J

james

Yep, I guess I misread, I was thinking of return from finally.
Which by the way is kind of a pain not being able to do that.


JIM
 
W

Wim Hollebrandse

So why would anyone want to return from within a finally block? Since
finally blocks are always executed, why not simply return after the full
try..catch...finally statement?

I suppose if you have so much logic in your finally block that you need to
return in some cases and not in others, it sounds like there's a problem
with the flow and design of the code.

Cheers,
Wim Hollebrandse
http://www.wimdows.com
http://www.wimdows.net
 
J

Jon Skeet

Wim Hollebrandse said:
So why would anyone want to return from within a finally block? Since
finally blocks are always executed, why not simply return after the full
try..catch...finally statement?

Because you may have some conditional behaviour in the finally block -
and also potentially because you wish to return in order to override
any exception which may have occurred. For instance, you could have
something like:

object GetValue (object defaultValue)
{
object ret = defaultValue;

try
{
ret = AttemptToGetRealValue();
}
finally
{
return ret;
}
}

Not something I'd often consider, admittedly (it masks too many
exceptions) - just an off-the-top-of-my-head example.
I suppose if you have so much logic in your finally block that you need to
return in some cases and not in others, it sounds like there's a problem
with the flow and design of the code.

There doesn't necessarily need to be *very* much logic in there. I'm
not saying I do it particularly often, but just occasionally it's
handy.
 
J

Jay B. Harlow [MVP - Outlook]

James,
Maybe its just me. :) I would simply put the return in the try block.

Something like:
int value = y;
try
{
val = doSomthing();
if ( val == X )
return true;
else
return false;
}
catch ( exception e)
{
//handle it
}
finally
{
}

I would suspect the finally block was doing too much, if it needed to decide
what the return value was.

Hope this helps
Jay

james said:
A more likely example is where the method return a boolean
like so


int value = y;
try
{
val = doSomthing();
}
catch ( exception e)
{
//handle it
}
finally
{
if ( val == X )
return true;
else
return false;
}

how can you be sure the proper return result is returned if
you do not catch the exception ??

JIM


Jon Skeet said:
Because you may have some conditional behaviour in the finally block -
and also potentially because you wish to return in order to override
any exception which may have occurred. For instance, you could have
something like:

object GetValue (object defaultValue)
{
object ret = defaultValue;

try
{
ret = AttemptToGetRealValue();
}
finally
{
return ret;
}
}

Not something I'd often consider, admittedly (it masks too many
exceptions) - just an off-the-top-of-my-head example.
need
 
J

Jon Skeet

Jay B. Harlow said:
Maybe its just me. :) I would simply put the return in the try block.

But then you've got to have another return statement either in the
finally block or after it, in case doSomething() throws an exception
which is caught.
I would suspect the finally block was doing too much, if it needed to
decide what the return value was.

Usually, yes - but *sometimes* it's handy.
 
J

Jon Skeet

Jay B. Harlow said:
Lets says there is no exception, the program proceeds to the finally block,
sees the return statement that returns a value. That mostly makes sense.
Now lets say an exception was thrown, but is not caught!, the program
proceeds to the finally block, sees the return statement with a value. Huh!
I'm in the middle of raising an exception, do I evaluate the return and
return the value, or do I continue raising the exception. Seeing as the
exception has precedence I ignore the value on the return (it is evaluated,
just not used) and continue to raise the exception.

Not in Java, at least - and if C# had return in finally, I'd expect it
not to be true in C# either. The last reason for terminating the method
(return or exception) is the one that takes priority. I realise this is
all hypothetical, but where did you get the "seeing as the exception
has precedence" idea from?

Unfortunately it's relatively hard to find any occasions in my existing
code where I've used return from a finally block - if I run into any in
the next few days, I'll post them. I don't expect to though - as I say,
I've only used it occasionally.
 
J

Jay B. Harlow [MVP - Outlook]

Jon,
all hypothetical, but where did you get the "seeing as the exception
has precedence" idea from?

I was trying to say that:

If you entered the finally block because of an exception, the block is
operating in the context of an exception handler, a value on the return is
immaterial.

If you entered the finally block as normal program flow (no exception), the
block is operating in the context of not being an exception handler, a value
on the return is material.

As you put it, the last reason for terminating the method (implicit or
explicit) return or an exception.

Jay
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top