Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / New Users / May 2004

Tip: Looking for answers? Try searching our database.

IDisposable.Dispose, Object.Finalize and threads

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Francois PIETTE - 05 May 2004 20:00 GMT
IDisposable.Dispose is documented as the method where you have to release
unmanaged resources.
Dispose is called by Finalize.
Finalize is called by garbage collector after the object becomes
inaccessible.
The documentation says: "The thread on which the finalizer is run is
unspecified".

So the question is: My object has allocated a [win32] window handle using
CreateWindow (called using P/Invoke) and has to destroy it. But Win32 SDK
say that DestroyWindow has to be called from the same thread that called
CreateWindow. This seems impossible given Dispose/Finalize/GC patern.

Any advice ?

btw: Let me know if I should post to another group.
Signature

francois.piette@overbyte.be
The author for the freeware multi-tier middleware MidWare
The author of the freeware Internet Component Suite (ICS)
http://www.overbyte.be

David Browne - 05 May 2004 21:19 GMT
> IDisposable.Dispose is documented as the method where you have to release
> unmanaged resources.
[quoted text clipped - 8 lines]
> say that DestroyWindow has to be called from the same thread that called
> CreateWindow. This seems impossible given Dispose/Finalize/GC patern.

Therefore you should implement IDisposable, but omit the finalizer.  Client
code should be clearly warned that failure to call IDisposable.Dispose will
leak a winow handle.

David
Chad Z. Hower aka Kudzu - 06 May 2004 08:59 GMT
> Therefore you should implement IDisposable, but omit the finalizer.  Client
> code should be clearly warned that failure to call IDisposable.Dispose will
> leak a winow handle.

Thats not a very good solution. Thats asking for trouble and in fact violates
the .NET guidelines in general.

I dont see any clean solutions either. Maybe a suspended thread for creating
and destroying - but that wont work either because the finalizer is not
allowed to make external calls.

Francois since I know you are a Borland user you might see what VCL.NET did
regarding this.

--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
     "Programming is an art form that fights back"
Francois Piette - 06 May 2004 12:47 GMT
> Francois since I know you are a Borland user you might see
> what VCL.NET did regarding this.

There are no problem with VCL.NET because in this context the destructor is
always explicitely called. The problem is with native .NET components when
they are used from languages likes C# where object destructors are only
called by the garbage collector.

--
francois.piette@overbyte.be
Author of ICS (Internet Component Suite, freeware)
Author of MidWare (Multi-tier framework, freeware)
http://www.overbyte.be

> > Therefore you should implement IDisposable, but omit the finalizer.  Client
> > code should be clearly warned that failure to call IDisposable.Dispose will
[quoted text clipped - 13 lines]
> Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
>       "Programming is an art form that fights back"
Chad Z. Hower aka Kudzu - 06 May 2004 13:09 GMT
"Francois Piette" <francois.piette@overbyte.be> wrote in news:409a267d$0$249
$4d4efb8e@read.news.be.uu.net:
> There are no problem with VCL.NET because in this context the destructor
> always explicitely called. The problem is with native .NET components

Thats not correct Francois. I know you and I are at odds a lot - but I am
giving two sessions on this at CTTM (SDC) so I know this area very very well
after weeks of research and experimentation. :)

BTW I forgot to tell you I was in Belgium again two weeks ago. But I'll be at
SDC next week. Would love if you can make it over an meet us just for even
lunch or something.

Ok back to tech.. In Delphi for .NET the destructors are NOT guaranteed to be
called. Destructors in Delphi are implemented as Dispose and are treated thus
the same. So unless the user calls Dispose (or Free or Destroy) from Delphi,
it will NOT be called.

> they are used from languages likes C# where object destructors are only
> called by the garbage collector.

Well kind of... C# destructors yes because they are implemented as a
finalizer. But a Delphi destructor is implemented as Dispose.....

--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
     "Programming is an art form that fights back"

Make your ASP.NET applications run faster
 http://www.atozed.com/IntraWeb/
Daniel Billingsley - 06 May 2004 11:54 GMT
But the Finalizer is not "supposed" to be called under normal circumstances.
It is a sign that the Dispose() was not properly called, as Dispose() should
call SuppressFinalize.

Look in the help for a section called "Implementing a Dispose Method".  In
addition to explaining all this, it gives code for the recommended pattern.

There's a growing school of thought that goes so far to say the Finalizer
should even raise an Exception to make it clear there is a bug (the
Dispose() not being called).  Your scenario seems like a good reason to do
that if the memory leak is a big issue.

> IDisposable.Dispose is documented as the method where you have to release
> unmanaged resources.
[quoted text clipped - 12 lines]
>
> btw: Let me know if I should post to another group.
Chad Z. Hower aka Kudzu - 06 May 2004 13:04 GMT
> But the Finalizer is not "supposed" to be called under normal
> circumstances. It is a sign that the Dispose() was not properly called,
> as Dispose() should call SuppressFinalize.

Thats not correct.

Dispose and Finalize are not the same and in many cases you need both. ONLY
in cases that the Dispose releases the resources that Finalize does should
you call SupressFinalize. This is not the case in most instances.

A file access might be an exmaple that this is. In the Dispose you free the
file handle, but in the Finalize you do it in case the user did not call
Dispose.

> There's a growing school of thought that goes so far to say the
> Finalizer should even raise an Exception to make it clear there is a bug
> (the Dispose() not being called).  Your scenario seems like a good
> reason to do that if the memory leak is a big issue.

Its problematic if the finalizer throws an exception. The GC generally just
ignores it and goes on. So who will see the exception?

--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
     "Programming is an art form that fights back"

Get your ASP.NET in gear with IntraWeb!
 http://www.atozed.com/IntraWeb/
Jon Skeet [C# MVP] - 06 May 2004 13:36 GMT
> > But the Finalizer is not "supposed" to be called under normal
> > circumstances. It is a sign that the Dispose() was not properly called,
[quoted text clipped - 5 lines]
> in cases that the Dispose releases the resources that Finalize does should
> you call SupressFinalize. This is not the case in most instances.

I disagree - in every case I can think of which I've come across,
Dispose releases the resources that the finalizer would other do.

Why would you *want* to wait until the object is finalized before
releasing resources if you've been explicitly told that the object will
no longer be used?

> A file access might be an exmaple that this is. In the Dispose you free the
> file handle, but in the Finalize you do it in case the user did not call
> Dispose.

So what's an example of it *not* being the case?

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Chad Z. Hower aka Kudzu - 06 May 2004 20:11 GMT
> I disagree - in every case I can think of which I've come across,
> Dispose releases the resources that the finalizer would other do.

It depends on how the resources are used and if the Dispose is a "Close" or
not. But I guess in most cases it would be the same - but not all.

> Why would you *want* to wait until the object is finalized before
> releasing resources if you've been explicitly told that the object will
> no longer be used?

In some cases the Dispose is more of a "Close" and shares code. But I guess
that if it left resources too - that wouldnt be a commonly needed situation.

--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
     "Programming is an art form that fights back"

Develop ASP.NET applications easier and in less time:
 http://www.atozed.com/IntraWeb/
Jon Skeet [C# MVP] - 06 May 2004 23:10 GMT
> > I disagree - in every case I can think of which I've come across,
> > Dispose releases the resources that the finalizer would other do.
>
> It depends on how the resources are used and if the Dispose is a "Close" or
> not. But I guess in most cases it would be the same - but not all.

Possibly not all, although I'd be interested to hear of an example.
Have you heard of any?

> > Why would you *want* to wait until the object is finalized before
> > releasing resources if you've been explicitly told that the object will
> > no longer be used?
>
> In some cases the Dispose is more of a "Close" and shares code. But I guess
> that if it left resources too - that wouldnt be a commonly needed situation.

Indeed - and the fact that I can't think of a single situation where
it's the case is fairly telling, I think.

Certainly I believe that your statement that "This is not the case in
most instances" (with regard to Dispose calling SuppressFinalize) in
untrue. (The docs for Dispose even state: "However, once the Dispose
method has been called, it is typically unnecessary for the garbage
collector to call the disposed object's finalizer.")

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

JD - 07 May 2004 00:32 GMT
The dataview is the only class that I have seen that "kind of" does the
close/dispose pattern. It inherits the MarshalByValueComponent that does
have a finalize method and implements the IDisposable interface. But if you
look in the dataview's constructor it calls GC.SuppressFinalize since it
doesn't have any unmanaged resources, so there is no need to override the
dispose method. But it does override the dispose method which calls the
close method which does some unregistering of events from the datatable.

Actually if you look at the dataview, it implements an interesting pattern
with the datatable in question, its member dvListener (type of
dataviewlistener), the dataview itself, and weak references. I haven't been
able to study the whole pattern but it looks like even if the dataview's
dispose/close method isn't called, the dataview will still be GC'd because
the dvlistener actually registers to the datatables events and the
dvlistener has a weak reference back to the dataview to communicate the
events. Like I said I haven't looked at the whole pattern but it looks like
the dvListener will still be around registered to the datatable's events and
would still hang around but the dataview will be GC'd.

> > > I disagree - in every case I can think of which I've come across,
> > > Dispose releases the resources that the finalizer would other do.
[quoted text clipped - 20 lines]
> method has been called, it is typically unnecessary for the garbage
> collector to call the disposed object's finalizer.")
Jon Skeet [C# MVP] - 07 May 2004 08:08 GMT
> The dataview is the only class that I have seen that "kind of" does the
> close/dispose pattern. It inherits the MarshalByValueComponent that does
[quoted text clipped - 3 lines]
> dispose method. But it does override the dispose method which calls the
> close method which does some unregistering of events from the datatable.

I don't see how that is quite what we were talking about. We were
talking about classes which implement IDisposable but which are still
finalized even is Dispose is called. The fact that SuppressFinalize is
called in the constructor instead of in Dispose is relatively
unimportant in this context - interesting though it certainly is.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

JD - 07 May 2004 10:36 GMT
>>> I disagree - in every case I can think of which I've come across,
>>> Dispose releases the resources that the finalizer would other do.

>>It depends on how the resources are used and if the Dispose is a "Close"
or
>>not. But I guess in most cases it would be the same - but not all.

>Possibly not all, although I'd be interested to hear of an example.
>Have you heard of any?

I thought it may be relevant in the thread of conversation above. The
dataview dispose method does not release resources that the finalizer does.
In this case the finalizer is taken out of the picture right at the
construction of the object, dispose is merely a managed resource cleanup.
Sorry if 'm mistaken.

> > The dataview is the only class that I have seen that "kind of" does the
> > close/dispose pattern. It inherits the MarshalByValueComponent that does
[quoted text clipped - 9 lines]
> called in the constructor instead of in Dispose is relatively
> unimportant in this context - interesting though it certainly is.
Chad Z. Hower aka Kudzu - 07 May 2004 18:42 GMT
> Possibly not all, although I'd be interested to hear of an example.
> Have you heard of any?

I ran across some in preparing my sessions. I dont have them right now and I  
have to leave tommorrow for the conference. They arent "most" as I stated
incorrectly before, but they do exist.

> Certainly I believe that your statement that "This is not the case in
> most instances" (with regard to Dispose calling SuppressFinalize) in
> untrue. (The docs for Dispose even state: "However, once the Dispose

Yes, the most was not a correct statement.

--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
     "Programming is an art form that fights back"

Get your ASP.NET in gear with IntraWeb!
 http://www.atozed.com/IntraWeb/
Daniel Billingsley - 07 May 2004 12:29 GMT
> Thats not correct.

Well, it is according to Microsoft's .NET Framework Developer's Guide topic
"Implementing a Dispose Method" available in Visual Studio Help:
"A Dispose method should call the GC.SuppressFinalize method for the object
it is disposing. If the object is currently on the finalization queue,
GC.SuppressFinalize prevents its Finalize method from being called. Remember
that executing a Finalize method is costly to performance. If your Dispose
method has already done the work to clean up the object, then it is not
necessary for the garbage collector to call the object's Finalize method."

In regards to the example code for the Dispose/Finalize pattern given:
"The Finalize method calls the Dispose method that takes parameters, passing
false. You should not re-create Dispose clean-up code within the Finalize
method"

Did that author not have any idea what he was talking about?  It's not the
only place I've seen this pattern, BTW.

> Dispose and Finalize are not the same and in many cases you need both.
Of course.  When did I suggest otherwise?  In fact, I'd say you always
should include both, but ideally the Finalizer should never be needed.

>the Dispose you free the
> file handle, but in the Finalize you do it in case the user did not call
> Dispose.
Sounds pretty much like what I wrote, except I pointed out that these days
it is becoming pretty mainstream to consider the client not calling Dispose
as being a "bug", not just something oh well we'll clean up for him.
Jon Skeet [C# MVP] - 07 May 2004 13:15 GMT
> > Dispose and Finalize are not the same and in many cases you need both.
> Of course.  When did I suggest otherwise?  In fact, I'd say you always
> should include both, but ideally the Finalizer should never be needed.

You shouldn't always include both. If the class only deals with managed
resources (which may themselves contain unmanaged resources) you only
need a Dispose method.

StreamReader/StreamWriter is a good example of that - it includes a
Dispose method which calls Dispose on the underlying stream, but
there's no need to include a finalizer in it, as the stream itself will
have one if it needs it.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

David Browne - 07 May 2004 14:27 GMT
> > > Dispose and Finalize are not the same and in many cases you need both.
> > Of course.  When did I suggest otherwise?  In fact, I'd say you always
[quoted text clipped - 8 lines]
> there's no need to include a finalizer in it, as the stream itself will
> have one if it needs it.

Also with purely managed resources, Dispose should sometimes be used to
prune dead objects from longer-lived objectcs which reference them.

For instance event consumers should unregister thier event handlers in
Dispose, making them elegible for GC sooner, but should not have a finalizer
because by the time the finalizer runs the whole tree has become
unreachable.

David

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.