When does the Finalize event of a class fire?

B

Barry Flynn

VB 2005.

I have the following code in a Sub.

Dim oFred As SillyClass
oFred = New SillyClass
oFred.Gloop()
oFred = Nothing

Exit Sub

The Finalize code in the class does not fire until the .exe is closed.
I expected it to fire at either:-
- the point at which oFred is set to Nothing, or
- the point at which we exit from the Sub, and variable oFred goes out of
scope.

What are the rules governing when the Finalize code runs?

Thanks

Barry
 
P

Phill W.

Barry said:
The Finalize code in the class does not fire until the .exe is closed.
I expected it to fire at either:-
- the point at which oFred is set to Nothing, or
- the point at which we exit from the Sub, and variable oFred goes out of
scope.

Read up on "Garbage Collection" and the "IDisposable" pattern (or
Interface).

The CLR will reclaim only Managed memory /if/ and when it needs to, i.e.
when it needs to allocate some /more/ memory to something else. For a
program as simple as the one you showed, it doesn't need to do so, so
the memory doesn't get reclaimed until the program dies.

Setting objects to Nothing in Visual Basic is [usually] a pointless
exercise. It does /not/ get rid of the object but, instead, just makes
it "eligible" for Garbage Collection which, as I've said, might take a
very long time to run and get rid of the object.

Please Note: This usually /does not/ matter.

You only need to "worry" about it if your class uses any "unmanaged"
resources. A simple example might be a file that you use for munging
data around through some external tool; when your object dies, it really
ought to "tidy up" (delete) its temporary file.

For things like this, implement the IDisposable pattern and have your
"client" code call the object's Dispose() method.

Class X
Implements IDisposable

Sub Finalize()
Me.Dispose( False )
End Sub

Public Sub Dispose()
Implements IDisposable.Dispose

Me.Dispose( True )

' If we've cleaned up after ourselves, we can /lighten/
' GC's load by telling it to /ignore/ this object.
GC.SuppressFinalize( Me )

End Sub

Private Sub Dispose( ByVal disposing as Boolean )
If ( disposing ) Then
' Called from "our" code, we can kill off "related" objects

If ( File.Exists( m_sTemporaryFilePath ) ) Then
File.Kill( m_sTemporaryFilePath )
End If

End If

' Otherwise, we've been called from the finaliser,
' Other objects may or may not exist,
' so we only do our /own/ stuff.

End Sub

End Class


Module Y
Sub Main()
Dim x2 as New X()

x2.DoSomething()
x2.DoSomethingElse()
x2.DoSomethingElseAgain()

' then, the important bit
x2.Dispose()

End Sub
End Module

HTH,
Phill W.
 
C

Cor Ligthert[MVP]

Barry,

It is managed code, which means as you have to bother about finalizing, then
start again with your design.

The clean up is done by Net, as it is fact so difficult that you cannot do
that anymore yourself.

Cor
 
R

rowe_newsgroups

The clean up is done by Net

Dangerous words Cor.

I know that this is a very sore topic between us, but in my opinion
you can help .NET do the clean up by calling Dispose on IDisposable
objects when you're done with them and not letting this be done by the
GC / Finalizer.

Thanks,

Seth Rowe [MVP]
 
R

Rory Becker

The clean up is done by Net
Dangerous words Cor.

I know that this is a very sore topic between us, but in my opinion
you can help .NET do the clean up by calling Dispose on IDisposable
objects when you're done with them and not letting this be done by the
GC / Finalizer.


Since Moving to VB 8 and then 9 in quick succession I have found the new
"Using" keyword very useful here.
 
C

Cor Ligthert[MVP]

Seth,

There is a differnce what you can do and what you should do.

What is the sense to clean up memory and resources as there is more then
enough available, while the managed code can do that in fact better and
cleaner.

It sounds for me a little bit the same as that you remove every evening
almost all the petrol out of your car to be able to go to a gas station in
the morning and be able to get every morning the same new quantity of
petrol.

However, if you like to do that, feel free.

Cor
 
C

Cor Ligthert[MVP]

You mistunderstood my message however, something you added is something I
disagree with you.

In my idea you should use dispose as it is needed and were it is made for,
not because that is there given because it is inheritted by component.

I have too often read the sentence, it is a method in the class so it is
best practise to use it. I get the idea you write that in a way.

It is for me not good practise to use an method, just because that it is in
a class. I don't use ToString as I need to count two integers.

Dim a as integer = 1
Dim b as integer = 1
Dim C as integer = Cint(a.ToString) + Cint(b.ToString)

In that way as is written so often wrong about dispose this above would be
also best practise. For me it's not.

There is in my idea nothing wrong with doing someting twice as that makes
the total proces shorter, especially as that is done at the best managed
moment.

(This including that the "using" automaticly executes dispose, what makes
the using at least more simple to describe)

Which does not mean that I don't use dispose, I always use that for drawing
objects, dialogforms, etc.

Just my idea.

Cor
 
C

Cor Ligthert[MVP]

Tom,
I'm not sure I get you here? Not calling dispose can negatively affect
the
performance of the gc, because it normally has to make two passes to
remove and
object that implements idispose if dispose insn't called... That has
nothing
to do with being disposable of course - but the fact that most objects
that
implement IDisposable also include a finalizer. How is that in anyway a
good
thing?
I have seen that the GC works as the video processor is doing its job, I am
not completely sure of that, but as it is like that, it is in fact null
time, while your dispose takes needed proces time.

I agree that this is not for non video processes. I am working at one at the
moment, it runs at night, nobody cares if it takes 2 or 6 hours.

Cor
 
R

rowe_newsgroups

Tom,




I have seen that the GC works as the video processor is doing its job, I am
not completely sure of that, but as it is like that, it is in fact null
time, while your dispose takes needed proces time.

I agree that this is not for non video processes. I am working at one at the
moment, it runs at night, nobody cares if it takes 2 or 6 hours.

Cor

I'm not sure how many times we've been through this conversation on
the newsgroups, but I'm sure we've covered all your arguments and
proved them to be rooted in misinformation or just plain wrong. I've
also seen this topic enough to know it doesn't really matter what
arguments we give, you aren't going to change your opinions. For this
reason I encourage readers of this thread who want the "full" debate
to do some searching in the archives.

However, just to restate my opinion, I believe you you should use
IDisposable every time unless you are absolutely sure that there is no
reason to call it (such as Cor's example of inherited Components).
This has nothing to do with calling the method simply because it
exists (such as Cor's attempt at saying this through his "ToString"
sample), it has to do with calling the method since the developer's
say it is necessary (even though sometimes it is not). Personnally, I
would not allow code to go to production that does not use the Dispose
functionality where it is needed (db transactions, streams, graphics,
etc). This to me is a worse "no-no" than writing code without having
Option Strict turned on.

Thanks,

Seth Rowe [MVP]
 
C

Cor Ligthert[MVP]

Seth,

What do you want to say with your complete message. You write exactly how I
think and always write about it.

Even in this thread I have explicitly given situations where it should be
used.

But that as well as you create your own classes where IDispose is not
implemented and unmanaged resources are used.

But not as you always tells to dispose things as datatables, datasets or a
Sqlconnection (the latter has the dispose implemented in the close).

So what do you mean with this cheap agusing message what tells nothing then
some demagogie.
 
R

rowe_newsgroups

I'll do my best to answer your questions Cor, though I am having a bit
of trouble understanding some of what you are saying here.
What do you want to say with your complete message. You write exactly how I
think and always write about it.

The purpose of my message was to encourage readers to find the
previous threads where we have been over this.
Even in this thread I have explicitly given situations where it should be
used.

Again, many of the areas where we differ in opinion is whether or not
you should call Dispose if you do not know whether it is needed. We've
covered this in other threads, and so as to not waste time here I will
not go over it again.
But that as well as you create your own classes where IDispose is not
implemented and unmanaged resources are used.

Are you saying that I never reference unmanaged code in my projects?
If so you are a fool for assuming that I don't do this. And I assure
you that when I reference unmanaged code I implement IDisposable for
cleanup.
But not as you always tells to dispose things as datatables, datasets or a
Sqlconnection (the latter has the dispose implemented in the close).

Close and Dispose methods do different things. Again so as to not
waste time please read the following thread:

http://groups.google.com/group/micr...a387?lnk=gst&q=close+dispose#5d7e0a66a380a387
So what do you mean with this cheap agusing message what tells nothing then
some demagogie.

I have no idea what demagogie is, but I'll attempt to answer what I
think you are asking.

Not sure how I could get any clearer. You have listed many arguments
against using the IDisposable pattern as it was intended and I and
many others have shown you in previous threads where you are mistaken,
however I don't think you have ever changed your opinion. Remember
though Cor, just because you don't understand why you are wrong or you
refuse to admit you are wrong does not mean you aren't still wrong.

Some of the many things you have said which I believe are blatantly
wrong are:

That calling Dispose is the same as calling ToString()
The Garbage Collector cleans up any resource better without any
interaction by the developer
The Garbage Collector runs during "idle" times and never affects
performance
Dispose should be avoided unless you absolutely know it must be called
More I'm sure I've forgotten

Again, I'm not going to list rebuttals here, I encourage readers to
use the archives and find the previous threads and form their own
opinions. As for me, I'm dropping this thread.

Thanks,

Seth Rowe [MVP]
 
C

Cor Ligthert[MVP]

Seth,

snip
http://groups.google.com/group/micr...a387?lnk=gst&q=close+dispose#5d7e0a66a380a387
snip

In my idea you really should take some more time before you write something.
This was the situation in 2002 were was told that the connection dispose was
overloaded with the removal of the connection from the connectionpool. In
fact that has nothing to do with the dispose. To Implement Dispose to remove
*unmaneged resources* be done by this.

http://msdn.microsoft.com/en-us/library/fs2xkftw(VS.85).aspx

Luckely is IDisposable standard implemented in th by the designer created
templates like Form and Component where that is needed.

I have the ides, that what you are talking about all the time is the in my
idea the overloaded Dispose (boolean) method, which is strongly adviced not
to use on its own.

Things as DataTables don't need dispose because it is only a bunch in memory
objects, which have not any unmanaged resource.

By the way, the by you refered message is more times corrected by Pablo
Castro. Here just one I found. Maybe you could use Google in future and not
come direct with something you found from 2002, while giving the idea in
your message that I had to do with it while I was not.

http://groups.google.com/group/microsoft.public.dotnet.framework.adonet/msg/7111c0671640ad38

Maybe you can use Google to find something Jay B. Harlow wrote, he did made
before he wrote that forever the same discussions like you with me about
dispose.

Then he did some investigation in it and wrote the article. In that article
Jay B. made more clear where dispose should be used. His article was mainly
covering the aspects as I write about dispose. But he added some for me new
aspects, which I use when I write about dispose, by instance the dispose of
the dialogs, which I did but I did not know why before his article.

Cor
 

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