Finally - what does it do?

G

Guest

Maybe I'm missing something here, but I can't see the purpose of the
'finally' keyword. What is the difference between:
try
{
doSomething()
}
catch
{
handleError();
}
finally
{
tidyUp()
}

and

try
{
doSomething()
}
catch
{
handleError();
}
tidyUp()

as far as I can tell in both cases tidyUp() gets executed whether an
exception occurs or not.
 
G

Guest

Finally allways runs regardless of the results of the try-catch block.

You could use it to release objects, for instance...

Without the Finally block in the following you, the console window would
close before you (or at least I) could read either response WriteLine().

static void Main(){
Console.WriteLine("Is it a weekday (1) or weekend (0)?");
string strX = Console.ReadLine();
int intX = int.Parse(strX);
try{
double dblX = 1/intX; //cause divide by zero error
Console.WriteLine("Its a Weekday");
}
catch{
Console.WriteLine("You can't do work on the weekend...\n");
}
finally{
Console.ReadLine();
}
}
 
M

Marina

In your example, none. But there are other ways to use it:

Such as:

try
{
doSomething();
return true;
}
catch
{
handleError();
return false;
}
finally
{
tidyUp();
}

or:

try
{
doSomething();
}
finally
{
tidyUp();
}
 
G

Guest

But wouldn't it woek just as well if you put:
static void Main(){
Console.WriteLine("Is it a weekday (1) or weekend (0)?");
string strX = Console.ReadLine();
int intX = int.Parse(strX);
try{
double dblX = 1/intX; //cause divide by zero error
Console.WriteLine("Its a Weekday");
}
catch{
Console.WriteLine("You can't do work on the weekend...\n");
}
Console.ReadLine();
}
 
G

Guest

Well, I'm not convinced. In the first example surely the finally block will
never be executed anyway, as the method returns from the try block and from
the catch block. The second one is silly, why would you write a try blok with
no catch block - and anyway, would the finally block be executed after an
unhandled exception??
 
O

Oliver Sturm

Dave wrote:

as far as I can tell in both cases tidyUp() gets executed whether an
exception occurs or not.

No. Actually your sample is a good one because you call handleError() in
your catch block. What if handleError throws an exception itself? You
always have to assume that a method you call might throw an exception.
So the variant with the finally block will still execute the tidyUp
method, but the other one may not.

Often this is more difficult to show when there's really nothing
happening in the catch block at all, but with a call to an external
method it's really easy to see, that's why I said your sample is a good one.



Oliver Sturm
 
G

Guest

Hmm. Now that raises an interesting question which hadn't occurred to me in
all my many years of C++ programming. What happens if an exception is thrown
within a catch block? Does it get caught by the same catch block? Can you put
a try block within a catch block?
You seem to be saying the same as Marina, which is that the finally block is
executed following an unhandled exception, while code that follows the catch
block is not. Is that correct?
 
R

Reginald Blue

Dave said:
Maybe I'm missing something here, but I can't see the purpose of the
'finally' keyword. What is the difference between:
try
{
doSomething()
}
catch
{
handleError();
}

All other comments aside, this little set of code falls in the "not
recommended" category. This will catch a whole host of errors which may not
be recoverable, and yet you continue on anyway. This way leads to madness.

Ultimately, finally is most useful without catch:

try
{
doSomething();
}
finally
{
doGuaranteedCleanup();
}

--
Reginald Blue
"I have always wished that my computer would be as easy to use as my
telephone. My wish has come true. I no longer know how to use my
telephone."
- Bjarne Stroustrup (originator of C++) [quoted at the 2003
International Conference on Intelligent User Interfaces]
 
B

Bill Butler

Dave said:
Maybe I'm missing something here, but I can't see the purpose of the
'finally' keyword.
<snip>

Hi Dave,

finally is much more important when you don't want to catch the exception in
the original try/catch/finally block.
Without "finally" you would need to catch and rethrow all exceptions.

Try to rewrite your example so that it bubbles up the exception and you get
cleanup code in multiple places.
instead, try the following

void Function()
{
try
{
Blah();
}
finally
{
Cleanup(); // cleanup always occurs
}
}

static void Main()
{
try
{
Function();
}
catch
{
HandleException();
}
}

----------------------------------------
Or

void Function()
{
try
{
Blah();
}
catch (SpecificExceptionThatICanHandle ex)
{
HandleException();
}
finally
{
Cleanup(); // cleanup always occurs regardless of the type of
exception thrown
}
}

static void Main()
{
try
{
Function();
}
catch (Exception ex)
{
HandleAllExceptions();
}
}

Hope this helps
Bill
 
M

Mats-Lennart Hansson

A finally is ALWAYS called after a try {} catch {} regardless of which was
executed.

This means that it is called even if the try (or call) code returns
something. This can save you some code like in the example below. As you can
see you don't have to write cleanup code twice but only in the finally
clause.

/Mats-Lennart

try
{
// Do something
return true;
}
catch
{
// Do something
return false;
}
finally
{
// Clean up
}
 
G

Guest

Dave said:
But wouldn't it woek just as well if you put: and
Well, I'm not convinced.

convinced? work?

I thought you just wanted some anonymous, self-righteous, speed-typer to
quote the documentation and pass it off as authority.
Hell if Microsoft isn't requried to provide a real explanation, why should
we? (that's an attempt at sarcasm Dave... come on laugh!! Here's another
one, "C# isn't Java").

I think the intent is to ensure that any error thrown (even one within the
try-catch block) will not prevent the app from completing some important task
 
M

Marina

Yes, in the first example it will execute. That is the whole point.

And yes, in the second example it will execute after an exception. That is
the whole point! That this method does not know how to deal with exceptions,
so it will allow the exception to go up to the caller, but it still wants to
make sure it closes all its resources before the method is done.

I think you don't even understand how the finally block works, and when it
works, so everything is labeled as 'silly'?

Obviously it's there for a reason, otherwise it wouldn't have been added to
the language.
 
T

The Last Danish Pastry

Well, I'm not convinced. In the first example surely the finally
block will
never be executed anyway, as the method returns from the try block
and from
the catch block.

Nope. The 'finally' block will _always_ be called, whichever return is
invoked. Try it!

The second one is silly, why would you write a try blok with
no catch block - and anyway, would the finally block be executed
after an
unhandled exception??

Try without catch is a common, and useful, construct.
 
B

Bill Butler

Dave said:
Well, I'm not convinced. In the first example surely the finally block
will
never be executed anyway, as the method returns from the try block and
from
the catch block.
<snip>

I suggest that you test this assumption of yours.
Try this

static void Main()
{
Console.WriteLine("Function(0):{0}",Function(0));
Console.WriteLine("Function(1):{0}",Function(1));
}

static bool Function(int x)
{
try
{
Console.WriteLine("try");
if(x>0)
throw (new Exception());
Console.WriteLine("try:after throw");
return (true);
}
catch
{
Console.WriteLine("catch everything");
return (false);
}
finally
{
Console.WriteLine("finally");
}
}
------------------------------------------
Output:
try
try:after throw
finally
Function(0):True
try
catch everything
finally
Function(1):False
-----------------------------------------

finally gets called BEFORE returning!!!
This is a highly unintuitive, but very nice feature.

Bill
 
O

Oliver Sturm

Dave said:
Hmm. Now that raises an interesting question which hadn't occurred to me in
all my many years of C++ programming. What happens if an exception is thrown
within a catch block? Does it get caught by the same catch block? Can you put
a try block within a catch block?

The latter, yes. An exception thrown in a catch block will not be caught
by that same catch block. You'd have to introduce another catch block to
make sure the exception won't be thrown up the hierarchy.
You seem to be saying the same as Marina, which is that the finally block is
executed following an unhandled exception, while code that follows the catch
block is not. Is that correct?

Right, that's just the purpose of the finally block. This is where you
want to put code that's to be executed under any circumstances, whether
an exception has been thrown in the encapsulated code or not.

Another thing I thought of with regard to your samples is this: What if
you wanted to rethrow the exception you caught? You might decide in the
catch block that you can't do anything about the exception you caught
and rethrow it for someone else to deal with. In that case, only the
code in the finally block would be executed, once again, because there's
again an uncaught exception.



Oliver Sturm
 
T

The Last Danish Pastry

A finally is ALWAYS called after a try {} catch {} regardless of
which was executed.

This means that it is called even if the try (or call) code returns
something. This can save you some code like in the example below. As
you can see you don't have to write cleanup code twice but only in
the finally clause.

/Mats-Lennart

try
{
// Do something
return true;
}
catch
{
// Do something
return false;
}
finally
{
// Clean up
}

And does anybody know what is the result of...

private int What()
{
try
{
return 6;
}
finally
{
return 7;
}
} // What

without actually trying it. I didn't :)
 
M

Marina

That shouldn't compile, as you shouldn't be allowed to have the 'return 7'
in the finally block.
 
N

Nick Malik [Microsoft]

Hello Dave,
Well, I'm not convinced. In the first example surely the finally block
will
never be executed anyway, as the method returns from the try block and
from
the catch block.

Not true. Even if you return from a try or catch block, the finally block
is executed before the return.
The second one is silly, why would you write a try blok with
no catch block - and anyway, would the finally block be executed after an
unhandled exception??

You would code a try block with a finally if you have created an unmanaged
object and you want to make sure that you release it even if you have an
unmanaged exception. In this case, the finally block will be executed even
if there is an unmanaged exception that is about to work its way up the call
stack.

This is actually quite a common pattern for objects that don't support
IDisposable.




--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
--
 
N

Nick Malik [Microsoft]

Hello again,

Dave said:
Hmm. Now that raises an interesting question which hadn't occurred to me
in
all my many years of C++ programming. What happens if an exception is
thrown
within a catch block? Does it get caught by the same catch block?

no. You'd need to embed another try-catch to catch an error that is thrown
in a catch block:

try
{
// screw up one
}
catch
{
try
{
// screw up again
}
catch
{
// catch the second failure
}
finally
{
// clean up the catch code
}
}
finally
{
// clean up after the first failure
}
You seem to be saying the same as Marina, which is that the finally block
is
executed following an unhandled exception, while code that follows the
catch
block is not. Is that correct?

yes.

--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
--
 
G

Guest

Absolutely right. Main idea of catch block is not to catch ALL types of
exceptions, but only ones you can handle. Example:
try{
//do something
}
catch (ExceptionType e){
//handle error
}
finally{
//clean up
}

You NEVER should catch exceptions you can't handle. In that way finally will
free resources even when unknown exception is thrown.
Reginald Blue said:
Dave said:
Maybe I'm missing something here, but I can't see the purpose of the
'finally' keyword. What is the difference between:
try
{
doSomething()
}
catch
{
handleError();
}

All other comments aside, this little set of code falls in the "not
recommended" category. This will catch a whole host of errors which may not
be recoverable, and yet you continue on anyway. This way leads to madness.

Ultimately, finally is most useful without catch:

try
{
doSomething();
}
finally
{
doGuaranteedCleanup();
}

--
Reginald Blue
"I have always wished that my computer would be as easy to use as my
telephone. My wish has come true. I no longer know how to use my
telephone."
- Bjarne Stroustrup (originator of C++) [quoted at the 2003
International Conference on Intelligent User Interfaces]
 

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