What's finally keyword good for?

K

K Viltersten

I feel a bit dense because i can't figureout the point with the keyword
finally.According to the MSDN, the followingexample shows the usage of it.//
try_catch_finally.cs
using System;
public class EHClass
{
static void Main()
{
try
{
Console.WriteLine("Executing the try statement.");
throw new NullReferenceException();
}
catch (NullReferenceException e)
{
Console.WriteLine("{0} Caught exception #1.", e);
}
catch
{
Console.WriteLine("Caught exception #2.");
}
finally
{
Console.WriteLine("Executing finally block.");
}
}
}
The way i figure, finally gets called both when there's
been an error and when there hasn't been one. So
why not go:

try {...}
catch(Exception) {}
doStuff();

instead of:

try {...}
catch(Exception) {}
finally {doStuff();}

?
 
K

K Viltersten

The way i figure, finally gets called both when there's
That's correct, and that's the whole point!

E.g. supposing at the beginning of the try{} block you instantiate objects
e.g. maybe a connection to a database, a file on the hard disk or maybe a
call to unsafe code. If the next line in the try{} block throws an
exception, these resources will remain in memory until / unless the GC
decides that they've fallen out of scope, if ever...

However, since the code in the finally{} block will run even if there is
an exception in the try{} block, it's the perfect place to clean up...

Perhaps i wasn't clear in my question. I realize the
usefulness of the code always being run at the end
of a try/catch. However, i don't see the point of
putting it into a finally-statement.

Please enlight me what's the difference in those
two cases, with respect to the functionality.

try {a();} catch {b();} finally {c();}
respectively
try {a();} catch {b();} c();

I simply can't see it.
 
J

Jon Skeet [C# MVP]

Please enlight me what's the difference in those
two cases, with respect to the functionality.

try {a();} catch {b();} finally {c();}
respectively
try {a();} catch {b();} c();

I simply can't see it.

You should almost *never* catch all exceptions. Suppose an exception
is thrown and you let it propagate - which happens *much* more often
than being caught, IME. A finally block lets you clean up resources
etc without having to explicitly catch the exception.

Do you use "using" statements already? If so, you're already
effectively using finally blocks.

This:

using (Stream x = GetStreamFromSomewhere())
{
// Body
}

is converted into something like:

Stream x = GetStreamFromSomewhere();
try
{
// Body
}
finally
{
if (x != null)
{
x.Dispose()
}
}

Jon
 
R

RedLars

Perhaps i wasn't clear in my question. I realize the
usefulness of the code always being run at the end
of a try/catch. However, i don't see the point of
putting it into a finally-statement.

Please enlight me what's the difference in those
two cases, with respect to the functionality.

try {a();} catch {b();} finally {c();}
respectively
try {a();} catch {b();} c();

I simply can't see it.

--
Regards
Konrad Viltersten
----------------------------------------
May all spammers die an agonizing death;
have no burial places; their souls be
chased by demons in Gehenna from one room
to another for all eternity and beyond.

Finally gives developers more flexibility.

How would you cleanup the resource in your example without finally if a
() throws an exception? Do you place the clean-up code inside the
catch? What if you forget to add a catch(..) ? What if you have
multiple catch statements? Do you always catch all exceptions after a
try or do you catch it in another method \ class ?`How do you then
clean-up resources?
 
P

proxyuser

K Viltersten said:
Please enlight me what's the difference in those
two cases, with respect to the functionality.

try {a();} catch {b();} finally {c();}
respectively
try {a();} catch {b();} c();

I simply can't see it.

There isn't any difference there. However, you shouldn't be writing code
like that very often except in small programs or at high levels of a larger
application. There are 2 examples I can think of where you'll use finally.
First is where you catch more specific exceptions than Exception. Second is
where you return before finishing the code.

Most often you'll write exception handling code like this.

try
{
....
}
catch (MyKindOfException exc)
{
}
finally
{
}

In this case, you are only on the lookout for certain types of exceptions.
As your programs get bigger, you'll stop catching Exception and start
catching more specific types of exceptions. The ones you don't handle get
bubbled up to code somewhere else. So you're using "finally" to do code
when an exception is thrown that you're not handling.

The second example is code like this.

try
{
if (something == null)
{
return;
}
}
catch
{
}
finally
{
}

In this case, the "finally" still gets executed before you actually exit the
function.
 
R

Registered User

On Mon, 8 Dec 2008 16:08:05 +0100, "K Viltersten"

\
Please enlight me what's the difference in those
two cases, with respect to the functionality.

try {a();} catch {b();} finally {c();}
respectively
try {a();} catch {b();} c();

I simply can't see it.

In both cases what happens if the method b throws an exception? In the
first case the method c will still be invoked. That is not the case
with the second scenario.

regards
A.G.
 
C

Chris Dunaway

Perhaps i wasn't clear in my question. I realize the
usefulness of the code always being run at the end
of a try/catch. However, i don't see the point of
putting it into a finally-statement.

Please enlight me what's the difference in those
two cases, with respect to the functionality.

try {a();} catch {b();} finally {c();}
respectively
try {a();} catch {b();} c();

I simply can't see it.

--
Regards
Konrad Viltersten
----------------------------------------
May all spammers die an agonizing death;
have no burial places; their souls be
chased by demons in Gehenna from one room
to another for all eternity and beyond.

In addition, what if there is an exception thrown in your catch block?
Or what if a *different* exception is thrown than the one you are
catching? With the first version you showed, the finally will still
be executed. With your second version, the code after the catch will
not be:

Consider this program:

class Program {
static void Main(string[] args) {

Console.WriteLine("Running with finally...");
try {
a(false);
}
catch (MyCustomException) {
b();
}
finally {
c(); //This will *always* be called
}

Console.WriteLine("Running without finally...");
try {
a(true);
}
catch (MyCustomException) {
b();
}

c(); //This will not be called

Console.ReadLine();
}

private static void a(bool throwAlternateException) {

if (throwAlternateException) {
Console.WriteLine("Throwing alternate exception.");
throw new AlternateException();
}
else {
Console.WriteLine("Throwing MyCustomException");
throw new MyCustomException();
}
}

private static void b() {
Console.WriteLine("Exception caught.");
}

private static void c() {
Console.WriteLine("Executing c.");
}
}

public class MyCustomException : Exception {
}

public class AlternateException : Exception {
}


Chris
 
K

K Viltersten

Please enlight me what's the difference in those
There isn't any difference there. However, you shouldn't be writing code
like that very often except in small programs or at high levels of a
larger application. There are 2 examples I can think of where you'll use
finally. First is where you catch more specific exceptions than Exception.
Second is where you return before finishing the code.

Most often you'll write exception handling code like this.

try
{
...
}
catch (MyKindOfException exc)
{
}
finally
{
}

In this case, you are only on the lookout for certain types of exceptions.
As your programs get bigger, you'll stop catching Exception and start
catching more specific types of exceptions. The ones you don't handle get
bubbled up to code somewhere else. So you're using "finally" to do code
when an exception is thrown that you're not handling.

The second example is code like this.

try { if (something == null) {return;} }
catch {} finally {}

In this case, the "finally" still gets executed before you actually exit
the function.

Ah, now i see! Thanks! In the specific case of mine,
there won't be much use for it then, as i only put a
bool to false upon an exception. Nevertheless, it's
nice to have caught up something new.

Thanks to everybody who contributed the examples
showing the difference. Really great info!
 
P

Peter Morris

try {...}
catch(Exception) {}
doStuff();

Not dense at all! Consider this

try
{
DoSomeStuff();
}
catch (IOException ioException)
{
LogException(ioException);
}
catch (InvalidOperationException invalidOperationException)
{
LogException(invalidOperationException);
}
CleanUp();


That works fine, but you might want the exception to be thrown anyway


try
{
DoSomeStuff();
}
catch (IOException ioException)
{
LogException(ioException);
throw;
}
catch (InvalidOperationException invalidOperationException)
{
LogException(invalidOperationException);
throw;
}
finally
{
CleanUp();
}
 
P

Peter Morris

In addition:

try
{
DoSomeStuff();
}
catch (Exception unexpectedException)
{
LogException(unexpectedException);
}
CleanUp();

What if LogException fails and throws an exception? CleanUp isn't called!

Basically, the only way to ensure your code is executed is to put it in a
"finally" block.
 
O

Ollis

K Viltersten said:
I feel a bit dense because i can't figureout the point with the keyword
finally.According to the MSDN, the followingexample shows the usage of it.//
try_catch_finally.cs
using System;

The way I see it, the code after the try/catch is the *finally*. I have
never used *finally*.

private void something()
{

try
{

}
catch
{

}

/// This is the *finally* code from this point. One may check conditions at
this point, but what happens here is the *finally*.

}
 
P

Peter Morris

private void something()
{

try
{

}
catch
{

}

/// This is the *finally* code from this point. One may check conditions
at
this point, but what happens here is the *finally*.

}

private void something()
{
try
{
}
catch
{
throw now Exception("Oh no it isn't!");
}
}


:)
 
O

Ollis

Peter Morris said:
private void something()
{
try
{
}
catch
{
throw now Exception("Oh no it isn't!");
}
}


:)

It's called poor programming, and one did not know what the abort conditions
were out of the gate. It shouldn't happen that one doesn't know the abort
conditions and what to do on a try/catch, IMHO.
 
C

Christophe Lephay

Ollis said:
It's called poor programming, and one did not know what the abort
conditions
were out of the gate. It shouldn't happen that one doesn't know the abort
conditions and what to do on a try/catch, IMHO.

Catching all exception in the first place was poor programming at a higher
magnitude and if you don't catch all of them, your code is not anymore
equivallent to a finally block.
 
O

Ollis

Christophe Lephay said:
Catching all exception in the first place was poor programming at a higher
magnitude and if you don't catch all of them, your code is not anymore
equivallent to a finally block.

Like I said, one should know the conditions of a try/catch and the
excpetions that need to be caught or dealt with in the exception for a given
situation(s).

Just because there is a try/catch does that mean that a *finally* is needed.

The only time I have implemeted a try/catch/finally is on a SQL connection
using the USING statement to make sure the connection was checked to be
closed and close the connection if opened, because the solution was keeping
state while continiously doing background processing with a Windows Service
application as an example.

If the exception is in an ASP.Net solution, there is no need for a *finally*
as the application is not keeping state and is gone anyway.
 
O

Ollis

Peter Duniho said:
You're welcome to your opinion. But very few would agree that catching
_every_ exception is the correct approach, even if it were possible to
know every exception that could occur (and it's not). You should catch
exceptions only if you know exactly how to deal with them.

I didn't say catch every exception. If one happens to be in code dealing
with SQL Server on a try/catch, then why should one be looking for anything
else?
There are more subtle examples, but the most obvious, clear one is an
OutOfMemoryException. This is almost never an exception that you're going
to be able to successfully handle. In fact, in the process of handling
the exception you could easily generate another OutOfMemoryException (note
that OOM isn't the only scenario in which an exception could occur during
the handling of a previous exception). A finally clause at least gives
you the opportunity to _try_ to clean things up as your program goes down
in flames (you may still not be successful, but that's a different matter).

Oh there are other excpetions within an exception, like writing to an
Eventlog and the Eventlog is full or writing to a SQL Server logging table,
and SQL Server is not avaiable.
The fact is, it's good to have a way in the code to _guarantee_ that your
code will be executed on a failure, and the "finally" clause is genuinely
the only elegant way to do that. Short of wrapping your entire method in
yet another try/catch/throw, there's no other way to accomplish that
behavior.

I would say maybe and maybe not, and it depends upon what is the purpose of
the *finally*.

I have seen *finally(s)* introduce more complication and more trouble as
well, and I have instrucked developers to remove unneeded *finally(s)*. They
give the reason 'that's how the book explained it' -- to always use the
*finally*.

And I say maybe and maybe not, and it depends the conditions.
 
B

Bill Richards

you understand the use of try { } catch { }
and you understand that when using try {} catch {} finally {} the code in
the finally{} block is always run

what you are *forgetting* is that if an exception is caught, you might want
to throw that exception after doing some logging so that the rest of the
system can act accordingly.

if I have the following

public void MyMethod()
{
try { /* some method*/ }
catch(SomeException se)
{
// all I want to do is logging here because we are expecting this
kind of exception
}
catch
{
// whoops, an unexpected exception, the system needs to know about
this one
throw;
}

// clean up code goes here, releasing some resources
}

The cleanup code will never get run when the exception is thrown in the
second catch {} block, and you could well run out of memory pretty soon.

The solution of course is to put your clean up code in a finally {} block.

:blush:)
 
C

Christophe Lephay

Ollis said:
Like I said, one should know the conditions of a try/catch and the
excpetions that need to be caught or dealt with in the exception for a
given
situation(s).

Most of the exceptions i have to deal with are because of broken invariants,
and i definitely don't want to catch them.

I'm not sure what your point really is : if you catch all exceptions, it is
poor coding. If you don't write production code like the one you posted,
then you shouldn't assume it was different for Peter, and qualifing his code
as being poor coding was pointless.
Just because there is a try/catch does that mean that a *finally* is
needed.

Nobody said finally was always needed...
If the exception is in an ASP.Net solution, there is no need for a
*finally*
as the application is not keeping state and is gone anyway.

....it is just needed when you use unmanaged resources, asp.net or not.

I don't have much use of finally either, because most of resources are
managed and i prefer using(...) otherwise. However, finally and using are
equivallent (as long as the class is IDisposable), but the code you posted
was not.
 
C

Christophe Lephay

Ollis said:
I would say maybe and maybe not, and it depends upon what is the purpose
of
the *finally*.

Finally and using(...) are simply the only features that can guarantee that
your code will be exception safe when dealing with unmanaged resources.
Exception safe means that your program or data won't be in undefined state.
I have seen *finally(s)* introduce more complication and more trouble as
well, and I have instrucked developers to remove unneeded *finally(s)*.
They
give the reason 'that's how the book explained it' -- to always use the
*finally*.
And I say maybe and maybe not, and it depends the conditions.

Agree. And the conditions are as stated above.
 
C

Christophe Lephay

"Christophe Lephay" <[email protected]> a écrit dans le message
de groupe de discussion :
(e-mail address removed)...
Exception safe means that your program or data won't be in undefined
state.
Exception safe means that your program or data won't be in undefined state
*if an exception should occur*.
 

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