What's finally keyword good for?

O

Ollis

Christophe Lephay said:
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.

I never said anything about catch all exceptions. That came from you not me.

And all that was stated by me is what was that not knowing about all
exceptions in a given situation was *poor* programming. I guess you'll make
of it what you want in the defense of this other person.
Nobody said finally was always needed...

That's not how I read it.
...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.

That's not true. You use a USING statement on an ADO.NET connection to a
databse server like Oracle and it blows with the connection open. The
application is keeping state while contiiously coming back to open a new
connection in the process. All that's going to happen is the database server
is going to run out of connections, unless one does something to close the
connection during the abort each time, because that USING is not doing it.
 
C

Christophe Lephay

Ollis said:
I never said anything about catch all exceptions. That came from you not
me.

Well, that came from the code you posted, but i don't doubt you don't write
this kind of code in production.
And all that was stated by me is what was that not knowing about all
exceptions in a given situation was *poor* programming.

I'm not so sure. Many exceptions are for debugging purpose (invariants
checking) and, in this case, the user has no responsability about them.
I guess you'll make
of it what you want in the defense of this other person.
???


That's not true. You use a USING statement on an ADO.NET connection to a
databse server like Oracle and it blows with the connection open. The
application is keeping state while contiiously coming back to open a new
connection in the process. All that's going to happen is the database
server
is going to run out of connections, unless one does something to close the
connection during the abort each time, because that USING is not doing it.

Hum. It seems to me very unlikely that the behavior you describe could be
related to the using instruction.
 
O

Ollis

Christophe said:
Well, that came from the code you posted, but i don't doubt you don't
write this kind of code in production.

I write code for BLL and DAL, and I don't write the kind of code you are
talking about that needs to be looking at a bunch of exceptions. One
shoe doesn't fit all situations.

Why start looking at a bunch of exceptions when one is looking for a
particular exception, knowing that the code is only going to throw a
certain type if exception?

I didn't know I had to elaborate as to why, based on the code I posted.
I thought it was pretty straight forward. I don't like using the
*finally*, and one doesn't have to use the *finally* to clean things up.
It's kind of simple. I like simple code. I have no need for complicated
code.

If you want to use the *finally*, then use it. It doesn't mean it's a
best practice.
I'm not so sure. Many exceptions are for debugging purpose (invariants
checking) and, in this case, the user has no responsability about them.

As far as I am concerned, an exception serves one purpose, which is to
control the path of code execution to continue processing or terminate
processing.

I have no other use for exceptions.
You made much to do about the code I have posted. Like I said, I don't
like using the *finally*, the code I posted by no means was the gospel.
It was just an example -- no more or no less.

This is one thing I don't like about this NG as people here tend to take
a simple example of something, blow it way out of proportion and blow it
to the Moon.
Hum. It seems to me very unlikely that the behavior you describe could
be related to the using instruction.

You mean you have never faced that bullet. A USING statement to make a
database connection and nothing aborts is OK with *close* and
*dispose* of the connection. One has a SQL command abort inside the
USING with a open connection and no *close* and *dispose* occurs, and
the connection is left open. It is what I have experienced, and the
bullet I have faced.
 
D

Dathan

I like simple code. I have no need for complicated code.

I think you and I would disagree on what "simple" means. "Finally"
also serves the purpose of avoiding code duplication, which, in
general, makes code simpler, not more complicated. If, using your
example, you need to close a SqlConnection after handling any of a
number of exceptions, it's better to do that in a finally{} block,
because it's simply less to remember than making sure it's included in
each of your exception handlers.

Also, like many programmers, I'm more interested in many cases in
making it "just work" before implementing robust error handling. But,
bowing to the eventual need to make it as bullet proof as possible, I
frequently write code similar to the following:

try
{
// some stuff
}
finally
{
// cleanup code
}

and go back to fill in exception handling for individual exceptions
later, knowing at least that in the mean time, if my code does throw
an exception, at least the resources in use will be cleaned up, and
when I do add exception-specific handling, I won't have to duplicate
that cleanup code in each handler.
 
B

Bjørn Brox

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

\

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.
If b() throws an exception the execution would never return to execute
c() in any cases?

This is C#, not c or c++.
 
M

Mr. Arnold

I like simple code. I have no need for complicated code.

I think you and I would disagree on what "simple" means. "Finally"
also serves the purpose of avoiding code duplication, which, in
general, makes code simpler, not more complicated. If, using your
example, you need to close a SqlConnection after handling any of a
number of exceptions, it's better to do that in a finally{} block,
because it's simply less to remember than making sure it's included in
each of your exception handlers.

Also, like many programmers, I'm more interested in many cases in
making it "just work" before implementing robust error handling. But,
bowing to the eventual need to make it as bullet proof as possible, I
frequently write code similar to the following:

try
{
// some stuff
}
finally
{
// cleanup code
}

and go back to fill in exception handling for individual exceptions
later, knowing at least that in the mean time, if my code does throw
an exception, at least the resources in use will be cleaned up, and
when I do add exception-specific handling, I won't have to duplicate
that cleanup code in each handler.

---------------------------------------------------------------------------

As you talk of SQL server, what other Exception handling would I be worried
about other than a SQL Exception?

private object GetSqlData(long ID)
try
{
USING SQL connection
{
do some SQL stuff
}
}
catch(SQLexception sqlex)
{
if (conncetion open)
{
close connection
}
throw sqlex;
}

---------------------

This is my *finally* path, which for me is always the successful path.

return object;

}
 
K

K Viltersten

I feel a bit dense because i can't figure out the point with the keyword
finally.According to the MSDN, the following example shows the usage of
it.
try_catch_finally.cs
<snip>

I believe we can all agree that this was a tricky
issue, indeed. I'm glad to have sorted that out
so that the next person who googles is, will get
a very detailed explaination.

Great!
 
P

Peter Morris

It's called poor programming,

No it isn't, not at all. For example

try
{
}
catch (IOException ioException)
{
LogException(ioException);
throw;
}
catch (ArgumentException argumentException)
{
//wrap it in a more general exception
throw new MyClassException(argumentException);
}

Both of these are very common requirements. It's good programming! Missing
out a finally block on code that *must* execute is poor programming.
 
P

Peter Morris

I didn't say catch every exception.

But unless you do the code after the try..catch block isn't guaranteed to
execute, and therefore it isn't the same as a finally block.
 
O

Ollis

Peter Morris said:
No it isn't, not at all. For example

try
{
}
catch (IOException ioException)
{
LogException(ioException);
throw;
}
catch (ArgumentException argumentException)
{
//wrap it in a more general exception
throw new MyClassException(argumentException);
}

Both of these are very common requirements. It's good programming! Missing
out a finally block on code that *must* execute is poor programming.

You're only looking at this from a narrow prespective. It's obvious that you
have not done N-tier programming invloving Web services, .Net Remoting, WCF
or in gerneral SOA.

One shoe doesn't apply to all situations and the *finally* is not one of
them that fits all situations.
 
O

Ollis

Peter Morris said:
But unless you do the code after the try..catch block isn't guaranteed to
execute, and therefore it isn't the same as a finally block.


I'll repeat this to here as well.
----------------------------------

You're only looking at this from a narrow prespective. It's obvious that you
have not done N-tier programming invloving Web services, .Net Remoting, WCF
or in gerneral SOA.

One shoe doesn't apply to all situations and the *finally* is not one of
them that fits all situations.
 
C

Christophe Lephay

Ollis said:
You're only looking at this from a narrow prespective. It's obvious that
you
have not done N-tier programming invloving Web services, .Net Remoting,
WCF
or in gerneral SOA.

You are assuming far too much.
One shoe doesn't apply to all situations and the *finally* is not one of
them that fits all situations.

The question is : does it *sometimes* apply ?
 
P

Peter Morris

You're only looking at this from a narrow prespective. It's obvious that
you
have not done N-tier programming invloving Web services, .Net Remoting,
WCF
or in gerneral SOA.

Riiiiight :) Except that's what I do all day every day :)

One shoe doesn't apply to all situations and the *finally* is not one of
them that fits all situations.

I only said that having a catch above some code is not the same as a finally
block, and as far as I can see that is still correct.
 
P

Peter Morris

You're only looking at this from a narrow prespective.

Yes, the very narrow perspective of a small piece of code with a "try" block
that has code which must *always* "finally" be executed.

It's obvious that you
have not done N-tier programming invloving Web services, .Net Remoting,
WCF
or in gerneral SOA.

Your assumption is incorrect, I write multi-tier business apps all day every
day.

One shoe doesn't apply to all situations and the *finally* is not one of
them that fits all situations.

I didn't say it did. I merely said that

try
{
}
catch
{
}
//This is not code that will *always* be executed


and that is a fact :)
 
O

Ollis

Peter said:
Riiiiight :) Except that's what I do all day every day :)

How long have you been doing it is another matter. :p
I only said that having a catch above some code is not the same as a
finally block, and as far as I can see that is still correct.

And that's your opinion, which I don't know what you're talking, because
I don't need the *finally*, and I avoid things that I don't need. My
*final* code execution is just the final code execution path.

If I need a *finally* to do something, then I might use it. So far, I
have not had the need.
 
O

Ollis

Christophe said:
You are assuming far too much.


The question is : does it *sometimes* apply ?

The bottom line is that I don't need it. If I have a need one day, then
you'll be the first to know.
 
O

Ollis

Peter said:
Yes, the very narrow perspective of a small piece of code with a "try"
block that has code which must *always* "finally" be executed.



Your assumption is incorrect, I write multi-tier business apps all day
every day.



I didn't say it did. I merely said that

try
{
}
catch
{
}
//This is not code that will *always* be executed


That's the *final* on the successful path. It will always be executed if
successful.

If I am on a catch, I am leaving, and on a particular catch, I might
have to do a little clean-up. I am not going to code myself into some
situation that needs the *finally*. It's that simple. You might get
yourself into that situation where you need a *finally*.
 
P

Peter Morris

How long have you been doing it is another matter. :p

I started writing multi-user business software for a living in 1994.

And that's your opinion

Actually it is a fact. If you understand it or not, it is still a fact.

If I need a *finally* to do something, then I might use it. So far, I have
not had the need.

Just because you don't know why you need it doesn't mean it has no use :)

try
{
var fs = new FileStream(fileName, ...........);
//Write stuff to the file
fs.Close();
ZipTheFileUp();
}
catch (IOException)
{
}
File.Delete(fileName);

Your file will not always get deleted. You might get any kind of exception,
especially as I am also calling ZipTheFileUp. In which case the File.Delete
only gets called *if nothing goes wrong*.
 
C

Christophe Lephay

Ollis said:
That's the *final* on the successful path. It will always be executed if
successful.

Finally means to be executed no matter if the operation was successful or
not. Thus, your "final when successful" doesn't make sense.

Anyway, i've been in this troll for too long now. Time to break this
infinite loop.
 
R

Registered User

Registered User skrev:
If b() throws an exception the execution would never return to execute
c() in any cases?
No, if an exception is thrown from the catch block c() will be invoked
from within the finally block.
try {a();} catch {b();} finally {c();}

Without the finally block if an exception is thrown from the catch
block c() will not be invoked
try {a();} catch {b();} c();

A simple console app will verify this behavior.
This is C#, not c or c++.
And the language matters because...?

regards
A.G.
 

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