Dispose Again!

  • Thread starter Thread starter Guest
  • Start date Start date
Thanks Jay.

Jay B. Harlow said:
Michael,
I sent a question or two to MS on this. I will post here if I get anthing
to satiate your questions & concerns....

Hope this helps
Jay
 
Scott M. said:
You have heard if from the horses mouth, over and over in this thread:

When a class uses unmanaged resources and exposes a Dispose method, call
the Dispose method.

This is what virtually all documentation on Dispose says. The rest of
this thread is academic.

Scott, no offense, but your every time I read your responses I am - for some
reason or other - reminded of the "Microsoft helicopter joke." While your
responses are - I'm sure - technically accurate, I'm not finding them overly
useful in addressing my only simple question. So I shall rephrase more
precisely: By *name*, *exactly* which classes, of the classes built into
the .NET Framework (*no user-created classes*), absolutely *require* the use
of Dispose() - and *exactly* which ones don't?

I don't need consultant-like broad generalizations and sound bites rehashed
from the Marketing Department. I need to know exactly which classes need to
be disposed and which do not. That's all. End of story.

If all you have is another quote from the Book of Architects like this one
(Chapter 12, Verse 13): "Useth Dispose only on classes uponeth which it is
required of thee, but neither on classes on which it is not exposed; nor on
classes that inherit it, excepting that it hath been overridden as a plague
of locusts upon the keyboard; or upon classes wherein thy development has
forsaken thy managed resources and delveth into thine pool of unmanaged
resources. Then shalt thou call they Dispose method. 'Thy Finalize shalt
not use thy Dispose in vain,' sayeth the Scott, 'only thine class user shall
ever calleth thy Dispose as this is the way of things.' And out of the
darkness the people cheered and feasted upon the potato chips and Mountain
Dew and they coded and were once again happy...", then you can, for all
intents and purposes, save it for surprise ending to a book.
 
OK Got it. Learn IL, then use Object Browser and Reflector to observe the
objects...

Y'Know, if someone would just write a book called ".NET Dispose() List" or
some such crap, with a complete listing of all built-in Framework classes
that require Dispose to be used, I'd be second in line to buy the damn
thing. I thought the .NET Framework was going to make life easier - but
sometimes it seems that old problems were just exchanged for their 21st
century equivalents.
 
The outer-workings of the class seem to be fairly simple. You look at the
properties and methods exposed and determine what functionality the class
provides. Maybe you have an example of what you're talking about and how
this relates to Dispose()? Thanks
 
Michael,
I'm not finding them overly useful in addressing my only simple question.
IMHO This thread has definitely shows that this is not a simple question!
:-)

I need to know exactly which classes need to be disposed and which do not.
That's all.
IMHO Its not that simple (yes I may even say it is down right esoteric ;-))

Consider objects that inherit from System.Windows.Forms.Form:

Dim dialog As New OptionsDialog ' inherits Form
dialog.ShowDialog()
dialog.Dispose()

Dim child As New MidChildForm ' inherits Form
child.Show()

The form in the "dialog" variable requires Dispose being called, while the
form in the "child" variable does not. As Form.Show causes the form to call
Dispose for you in the Close event. While ShowDialog does not; allowing you
to retrieve values from the dialog's controls after the user closes the
form.
By *name*, *exactly* which classes, of the classes built into the .NET
Framework (*no user-created classes*), absolutely *require* the use of
Dispose() - and *exactly* which ones don't?
Consider System.Windows.Forms.Label. It is correct to state, as others have,
you don't need to (explicitly) call Dispose on Label, as normally a Form
"owns" the label, when you dispose the Form the label will be (implicitly)
Disposed. http://www.vbinfozine.com/a_disposable_comp.shtml However I have
seen reports of some third party controls that don't dispose correctly when
placed on forms...

Hope this helps
Jay
 
Jay B. Harlow said:
Consider objects that inherit from System.Windows.Forms.Form:

Dim dialog As New OptionsDialog ' inherits Form
dialog.ShowDialog()
dialog.Dispose()

Dim child As New MidChildForm ' inherits Form
child.Show()

See, now we're making progress. Two down. Now how many classes does that
leave? :)
 
Jay,

I was always curious about this and because of this thread I tested it.
Dim dialog As New OptionsDialog ' inherits Form
dialog.ShowDialog()
dialog.Dispose()
I tested it just with a breakpoint in the showdialog at the disposing part.
(because that the dispose is overriden in every form is that easy)
When I do
dim frm as new form2
frm.showdialog
frm.dispose ' it is called directly
When I do
dim frm as new form2
frm.showdialog
frm.close ' the same routine is called when the mainform is closing.

I hope this helps

Cor
 
Michael,
See, now we're making progress. Two down.
I would consider it one type, that is System.Windows.Forms.Form.

Consider a variation of the sample:

Dim dialog As Form

dialog = New OptionsDialog
dialog.ShowDialog()
dialog.Dispose()

dialog = New OptionsDialog
dialog.Show()

Its the exact same form, however based on how it is shown (Form.ShowDialog
or Form.Show) changes if Dispose is needed or not...
Now how many classes does that leave? :)
The following page suggests there are 85 classes. I'm not sure if that only
includes types directly implementing IDisposable or if it includes types
that inherit IDisposable from a base class also.

http://www.vbinfozine.com/a_disposable.shtml


I think the rule that is tripping people up (including the way I have stated
things) is when IDisposable is in a base class (such as Component).

Hope this helps
Jay
 
Michael,

A factor I use (however learned from what I read) for dispose is how
big/(how many it include) is the resource that is used.

When you are using a big bitmap/pens, and you know that your program will
maybe run on computers with by instance not to much memory, than that can be
a reason to dispose it as soon as possible. (Another one for me is creating
a lot in a recursive loop).

And because that nobody knows that memory question in advance, is it for me
good practise to dispose those as soon as possible.

Probably you knew this already

:-)

Cor
 
I knew about the bitmaps and pens, but hadn't really thought about the
recursive loop issue. Thanks for the food for thought.
 
Ahh, one down, 85 times X variations to go :) It seems like there are a lot
more than 85 classes, however. But then again, I might be counting classes
that are automatically excluded by virtue of not implementing Dispose()
anyway.
 
Cor,
frm.showdialog
frm.close ' the same routine is called when the mainform is closing.
Yes same routine but for different reason, look at what the disposing
parameter is.


http://msdn.microsoft.com/library/d...fSystemWindowsFormsFormClassDisposeTopic1.asp

In my test it was called by Finalize not Dispose, which in the ShowDialog
case I would expect, as that is what the following states:
http://msdn.microsoft.com/library/d...rlrfSystemWindowsFormsFormClassCloseTopic.asp

Try putting Me.Close in a button click event on the form. Use both
Form.ShowDialog & Form.Show to show the form. Notice the difference?

Try the following code:

'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

Debug.WriteLine(disposing, "Dispose")

If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

Private Sub buttonClose_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles buttonClose.Click
Debug.WriteLine("Before close", "buttonClose_Click")
Me.Close()
Debug.WriteLine("After close", "buttonClose_Click")
End Sub

Public Shared Sub Main()
Dim dialog As New MainForm
dialog.ShowDialog()
Debug.WriteLine("Before close", "Main")
dialog.Close()
Debug.WriteLine("After close", "Main")

Application.Run(New MainForm) ' do dialog.Show

End Sub

Hope this helps
Jay
 
Michael,
Using the following in a VS.NET 2003 Windows Forms application I get:

Assemblies: 5
Types: 3384
Disposable: 226
Dispose: 132

There are significantly more then 5 assemblies in the entire .NET
Framework...


Const bindingAttr As BindingFlags = BindingFlags.DeclaredOnly _
Or BindingFlags.Instance Or BindingFlags.IgnoreCase _
Or BindingFlags.Public Or BindingFlags.NonPublic
Dim disposable As Type = GetType(IDisposable)
Dim countAssemblies As Integer
Dim countTypes As Integer
Dim countDisposable As Integer
Dim countDispose As Integer
For Each a As [Assembly] In AppDomain.CurrentDomain.GetAssemblies()
countAssemblies += 1
For Each t As Type In a.GetTypes()
countTypes += 1
If disposable.IsAssignableFrom(t) Then
Debug.WriteLine(t.FullName, "IDisposable")
countDisposable += 1
End If
Try
If t.GetMethod("Dispose", bindingAttr) Is Nothing Then
' No Dispose method.
Else
Debug.WriteLine(t.FullName, "Dispose")
countDispose += 1
End If
Catch ex As AmbiguousMatchException
Debug.WriteLine(t.FullName, "Dispose(s)")
countDispose += 1
End Try
Next
Next
Debug.WriteLine(countAssemblies, "Assemblies")
Debug.WriteLine(countTypes, "Types")
Debug.WriteLine(countDisposable, "Disposable")
Debug.WriteLine(countDispose, "Dispose")

NOTE: The "t.GetMethod" is an attempt to see if there is any Dispose method
declared on the type itself, as oppose to simply inheriting the method from
a base class...

Hope this helps
Jay
 
Michael,
This class follows the Dispose/Finalize pattern.

Both Dispose() & Finalize() call Dispose(Boolean).

Hope this helps
Jay
 
Your saying that Dispose is present because of the IDE and not the final
running application and that in that final running application, Dispose
has
no use.

Well, actually you didn't say that the first time, you said:

What I got from this was you saying "you don't need to dispose web form
controls at run-time". And this is not true. As you say an OleDb
connection object at run-time will be holding on to unmanaged resources that
do not have anything to do with GDI and so this connection object should be
disposed at run-time.
That is what I take issue with, that is what is completely false.

And, gee, your sarcasm is something we can do without as well. Do you
disagree that OleDb connections hold unmanaged resources? What part of
saying that an OleDb connection needs to be disposed at run-time do you
disagree with?
 
Hey Michael, take a breath and relax for a moment.

I'm not trying to provoke you or cause an argument and I'd appreciate it if
you laid off the sarcasm as I haven't thrown any at you.

What I said (and you have blown completely out of proportion) was in
response to a question that was asked for a simple and clear definition of
what dispose is. What you've said is correct. I haven't and am not
disputing it, so it's not necessary for you to continue to hammer me with
the same text over and over.

Believe it or not, there may be folks out there who may create classes from
scratch (not explicitly inheriting from anything) and may not know anything
about the Finalize() method (I think this thread proves that). These are 2
pretty reasonable assumptions.

In this circumstance, it would be the class designer's job to create a
dispose and the class user's job to know to call it. My comments weren't
really referring to existing classes.

That's all I was saying. I never said "a class can't be created where its
dispose method is automatically called by a finalizer". And since not all
finalizers do call dispose, in fact, since not all classes even have a
finalizer, I think my statement about dispose is pretty accurate.

Sorry if this keeps you up at night.



Michael C# said:
Scott M. said:
"It is up to the class user to call this method [Dispose]."

My original point, as desmonstrated by the Microsoft(tm)-sponsored
statement and code previously posted, is that the Finalize method can
call Dispose. The Finalize method is called via the GC. The GC normally
is not invoked by the "class user". It *can* happen; therefore the
statement is False.

Uh, well, if in your book can=false, then ok.

In my book the statement "It is up to the class user to call this method"
= false, as it is a documented fact that Dispose can be invoked by means
other than the "class user". Too easy Breezy.
In my book, if I build a custom class that inherits from object and I
create a Dispose method for it, the GC isn't going to do squat as far as
calling my Dispose method. So, would I be wrong to reverse your logic
and say that because it *might not* get called, my statement is true?
Sure!

If you invoke Dispose in the Finalize method, as Microsoft has done in the
previously supplied sample code, then there is the possibility that it can
be invoked by GC. If you don't, then for that *one particular class*, it
cannot happen. However, based on the wild assumption that you're not the
only person in the Universe developing classes for the Framework (or just
maybe you are?) and that not everyone does things precisely the way you do
(some might even use Microsoft's own sample code as a starting point...
then again, this could be another wild and crazy out-of-bounds
assumption), it seems reasonable to conclude that there is at least one
class out there in the world in which the Finalize method invokes Dispose.
That one, single, lonely class which was not developed the "Scott M Way"
makes your gross generalization "false".
 
Cor, have you lost your mind?!

I am quoting YOU. YOU SAID: "There is no need to dispose any object of
system.data."

And then you have gone on to say that you didn't say it and now you are
saying I am all the time writing something else. What are you talking
about?!

Go back and read your own posts, would you?
 

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

Similar Threads


Back
Top