-
Oct 28th, 2007, 11:38 PM
#1
Thread Starter
PowerPoster
Help me understand why 'Finally' supercedes 'Exit Sub'
This may be obvious to those of you who have been doing .NET for a good while, but in the example below, why is it that when I say "Exit Sub" the "Finally" code still executes? (I'm thinking the "Whatever" message should never execute, but of course it does.) It seems counter-intuitive to me ...
Code:
Private Sub Whatever()
Try
MsgBox("Hello")
Exit Sub
Catch ex As Exception
Finally
MsgBox("Whatever")
End Try
End Sub
"It's cold gin time again ..."
Check out my website here.
-
Oct 28th, 2007, 11:41 PM
#2
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
Because the whole point of a Finally block is to ensure that its contents are executed NO MATTER WHAT. The whole idea is that once you enter a Try block the associated Finally block is guaranteed to be executed, so you can place essential cleanup code there and know for sure that it will be executed.
Last edited by jmcilhinney; Oct 28th, 2007 at 11:55 PM.
-
Oct 28th, 2007, 11:52 PM
#3
Thread Starter
PowerPoster
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
OK, understood. That's something I'll have to watch out for (no early exits within a Try block that has a Finally part).
"It's cold gin time again ..."
Check out my website here.
-
Oct 28th, 2007, 11:57 PM
#4
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
Sometimes that's exactly what you want though. If it's not then you are misusing your Finally blocks because they should only ever contain code that you absolutely want executed. That said, you should avoid using Exit Sub anyway.
-
Oct 29th, 2007, 08:07 AM
#5
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
Finally blocks are an excuse to let your code quality drop to unaceptable levels.
-
Oct 29th, 2007, 08:14 AM
#6
Frenzied Member
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
Originally Posted by wossname
Finally blocks are an excuse to let your code quality drop to unaceptable levels.
That said, you should avoid using Exit Sub anyway.
Can you guys explain why you say that?
-
Oct 29th, 2007, 08:52 AM
#7
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
Originally Posted by wossname
Finally blocks are an excuse to let your code quality drop to unaceptable levels.
This is a nonsensical statement.
Finally blocks are great for cleaning up resources - closing streams and connections, etc. If you're putting processing in there, then you're doing something wrong, but ignoring finally blocks means that you're letting your code quality drop to unacceptable levels.
-
Oct 30th, 2007, 07:57 AM
#8
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
Since when do we have justify our blanket generalisations?
Originally Posted by Tom Sawyer
This is a nonsensical statement.
Finally blocks are great for cleaning up resources
I only mean that if you rely on something as arbitrary as a finally block you'll eventually end up disguising serious flaws in the way you do things.
Make your algorithm correct rather than dumping responsibility on the compiler.
I don't live here any more.
-
Oct 30th, 2007, 09:47 AM
#9
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
Originally Posted by wossname
Since when do we have justify our blanket generalisations?
I only mean that if you rely on something as arbitrary as a finally block you'll eventually end up disguising serious flaws in the way you do things.
Make your algorithm correct rather than dumping responsibility on the compiler.
woss, I don't know why you hate the finally block so badly... did it steal your lunch money or something?
Here is what I would consider a valid use of the finally block in a routine (even if its overkill to have the set to nothing statements on the objects)
Code:
Dim CN As SqlConnection = Nothing
Dim CMD As SqlCommand = Nothing
Dim DR As SqlDataReader = Nothing
Try
CN = New SqlConnection("OPEN SESAME")
CMD = New SqlCommand("GIVE ME RECORDS", CN)
CN.Open()
DR = CMD.ExecuteReader(CommandBehavior.CloseConnection)
If DR.HasRows Then
While DR.Read
'DO SOME OF RECORDS PROCESSING HERE
End While
End If
Catch ex As Exception
'ALERT USER OF ERROR PROCESSING DATA
Finally
If DR IsNot Nothing Then
DR.Close()
DR = Nothing
End If
If CMD IsNot Nothing Then
CMD.Dispose()
CMD = Nothing
End If
If CN IsNot Nothing Then
CN.Dispose()
CN = Nothing
End If
End Try
this should clean up objects in the case of any type of error here in this routine. I see nothing wrong with doing things this way, so if you feel there is an issue here please let me know.
Also as a side note, I have become a fan of using return instead of exit sub. I also don't think its bad practice to exit a subroutine if needed. It all depends on the reason why.
For example, what if I had a routine that displays information about the currently selected item in a listview.
Wouldn't you want the first line of that routine to be
Code:
If ListView1.SelectedItems.Count = 0 Then Return
or
Code:
If ListView1.SelectedItems.Count = 0 Then
MessageBox.Show("Please select a listview item first")
Return
End If
-
Oct 30th, 2007, 01:56 PM
#10
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
Originally Posted by kleinma
woss, I don't know why you hate the finally block so badly... did it steal your lunch money or something?
Yes, yes it did. I don't want to talk about it.
To be honest I can't think of a useful reason to have Finally unless you are going to throw an exception inside a catch{} block that the finally is attached to.
I don't live here any more.
-
Oct 29th, 2007, 04:02 PM
#11
Addicted Member
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
Quote:
That said, you should avoid using Exit Sub anyway.
Can you guys explain why you say that?
Yeah - I'd like some guidance on that, too.
-
Oct 29th, 2007, 04:16 PM
#12
Hyperactive Member
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
One thing I don't understand is the difference between using a Finally block & simply putting more code after the End Try. (Other than the idea that an Exit Sub inside the Try block should bypass that additional code.)
Hopefully that additional code would be in a second Try/Catch block-is there a penalty for using multiple Try/Catch blocks in the same Sub? Otherwise it seems to me that all you need do is ensure that both the Try & all the Catch blocks 'fall thru' to the following code for it to function as a Finally block.
-
Oct 29th, 2007, 04:48 PM
#13
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
Originally Posted by Tom Sawyer
This is a nonsensical statement.
Finally blocks are great for cleaning up resources - closing streams and connections, etc. If you're putting processing in there, then you're doing something wrong, but ignoring finally blocks means that you're letting your code quality drop to unacceptable levels.
You're right, it is a nonsensical statement... even more so when you yourself then use that statement without further explanation.
Originally Posted by penguin5000
Originally Posted by jmcilhinney
That said, you should avoid using Exit Sub anyway.
Yeah - I'd like some guidance on that, too.
It's premature functional ejection.... idealy, if something goes wrong, in a sound structure, you should be able to 1) recover and continue, 2) handle it and skip anything that may go wrong after that point. That said: Sometimes in real life the rules need to be broken.
Originally Posted by calvin-c
One thing I don't understand is the difference between using a Finally block & simply putting more code after the End Try. (Other than the idea that an Exit Sub inside the Try block should bypass that additional code.)
Hopefully that additional code would be in a second Try/Catch block-is there a penalty for using multiple Try/Catch blocks in the same Sub? Otherwise it seems to me that all you need do is ensure that both the Try & all the Catch blocks 'fall thru' to the following code for it to function as a Finally block.
I had trouble with this too....The point is that the code in the Finally will run NO MATTER WHAT. Even if the try fails... Finally runs. If the Try succeeds, Finally will run. It's guaranteed. What ISN'T guaranteed to run is the code that follows... especially if there is an exception. Let's say I have some database stuff in my try. If the connection fails, it drops down into my Catch, there I can log the error, then throw an error to the caller. Then in the Finally I can clean up the connection, close everything down and dispose of all my objects safely. IF I don't have the finally, as soon as I throw the exception, the sub would terminate, leaving my objects open (until the GC comes along, but there's no guarantee WHEN it will.)
-tg
-
Oct 29th, 2007, 05:17 PM
#14
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
Excellent post tg. Says it all really.
-
Oct 30th, 2007, 04:21 AM
#15
Addicted Member
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
Originally Posted by penguin5000
Quote:
Originally Posted by jmcilhinney
That said, you should avoid using Exit Sub anyway.
Yeah - I'd like some guidance on that, too.
It's premature functional ejection.... idealy, if something goes wrong, in a sound structure, you should be able to 1) recover and continue, 2) handle it and skip anything that may go wrong after that point. That said: Sometimes in real life the rules need to be broken.
OK - I understand that for when you're using Try ... Catch ... Finally - I'd always use a finally to tidy up the problem. My 'problem' is the statement - "avoid using Exit Sub".
I obviously WANT to program properly, and tend to use Exit commands when I simply don't need to continue with that sub/function anymore. Is that a correct way of using an Exit command - or SHOULD they be avoided in general?
-
Oct 30th, 2007, 04:31 AM
#16
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
Originally Posted by penguin5000
Is that a correct way of using an Exit command - or SHOULD they be avoided in general?
They do serve a purpose but they should be avoided in general. It is considered by many to be proper style to have only one point of exit from a method. In that case all code paths should lead to that point. Having multiple Exit statements makes for code that is harder to read and harder to maintain. There are some situations where it can simplify code, in which case it's a good idea to use it, but in most cases well-structured code won't need an Exit statement.
-
Oct 30th, 2007, 05:59 AM
#17
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
Although using an EXIT SUB is, as already said, sometimes easier and used for that reason...
We prefer to set BOOLEAN variables as a sub runs that indicate what should happen as it continues. Then you wrap logic further down the path in those IF/blocks.
This structure makes for easier to read code. And more important, at least for us, easier to maintain and enhance.
Code:
Dim booFoundAPC As Boolean = False
Try
drc.Connection = Dcn
drc.CommandType = Data.CommandType.Text
drc.CommandText = "Select ConfData From APC Where ConfItem='Created'"
strAPC = drc.ExecuteScalar.ToString
booFoundAPC = True
If strAPC Is Nothing Then booFoundAPC = False
Catch ex As Exception
booFoundAPC = False
End Try
If booFoundAPC Then
drc.CommandText = "Select ConfData From APC Where ConfItem='LOCK'"
strLock = drc.ExecuteScalar.ToString
.
.
.
booFoundAPC determines if we are going to continue to process through this sub for example. All the places it would be set to FALSE would be places that EXIT SUB could be used if you wanted to code in that fashion.
And in any place in the code that follow we could continue the concept of setting booFoundAPC to false so that subsequent If/blocks in the sub did or did not run. Or set other more descriptive booleans to true/false...
Last edited by szlamany; Oct 30th, 2007 at 06:21 AM.
-
Oct 30th, 2007, 09:31 AM
#18
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
But wouldn't the Finally BE a part of that algorithm? It's not up to the compiler if it's going to add the finally block or not.... it's up to the developer... and it's not arbitrary. It has a clearly defined role... and it's optional too. You don't HAVE to use it... just that some times it MAY be desirable to do so.
If one is tossing it in just to use it and for no reason at all... THEN it becomes arbitrary.
-tg
-
Oct 30th, 2007, 02:05 PM
#19
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
what about if in the try you open a DB connection, then try to fire off your command, but an exception occurs?
You are saying you should clean up the DB connection in the catch instead of the finally?
-
Oct 30th, 2007, 02:34 PM
#20
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
I'm saying you do what is most sensible for any given situation.
Databases are a good example actually. It would be weird to open a DB connection and send a query in the same function unless the entire and comprehensive goal of that function was to open the DB, do a single simple query, then close the DB and return the result. That situation is easily handled in the catch, or in a set of a few specific catches.
However a more common use would be to use a function to open the DB and nothing else. Then do the queries as required elsewhere then use another function to drop the connection. None of these things gain any benefit whatsoever from a finally block.
If you like finally blocks then use them if they are convenient at the time, but don't design your software around them. Please don't ask me anything else because I'm losing the will to live.
I don't live here any more.
-
Oct 30th, 2007, 02:45 PM
#21
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
If you lose your will, and you lose your will to live, that will just make it difficult for your heirs.
Finally seems to me to be a form of limitted abstraction. In Kleinma's example, he closes datareaders in the Finally block. I do that a fair amount, and do it for this reason: I love datareaders and keep them around as long as I can.
Ok, that wasn't the real reason. Actually, it would be reasonable to close the datareader in the Try block, but if an exception is thrown prior to closing the datareader, you would also have to check the state of the datareader and close it in the Catch block, which would mean that you would be duplicating the code between the two blocks. Therefore, the Finally block would be a safer route simply because the common code would be moved into a common execution location.
My usual boring signature: Nothing
-
Oct 30th, 2007, 02:47 PM
#22
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
Originally Posted by Shaggy Hiker
but if an exception is thrown prior to closing the datareader, you would also have to check the state of the datareader and close it in the Catch block, which would mean that you would be duplicating the code between the two blocks. Therefore, the Finally block would be a safer route simply because the common code would be moved into a common execution location.
exactly why I did it. Code consolidation...
-
Dec 7th, 2007, 02:42 AM
#23
Junior Member
Re: Help me understand why 'Finally' supercedes 'Exit Sub'
okay i was looking for exit codes for vb.........i can see that finally is better then putting the close code in the catch. and after catch.
lets psuedo this out.
try
open file
read file <-- error reading
catch
msg ("error")
finally
close file
If you dont have finally then you would have to put a close file after catch and in the catch in case of an error. finally makes it simpler by always closing the file no matter what.
thats my 2 cents. (a month later, but...oh well)
edit: i guess thats the same thing shaggy said its been along day.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|