Dispose Again!

  • Thread starter Thread starter Guest
  • Start date Start date
Well Michael, no offense to you, but I can do without your sarcasm and
seemingly personal attacks on me.

Your question makes perfect sense, and it is reasonable to think that a
simple, clear concise answer should be given. But, you know what Michael?
The answer isn't simple. To me, it seems that you want to blame me (or
someone) because the simple, clear, concise answer you seek doesn't exist in
that form.

I am not aware of any complete text that lists the do's and don'ts of what
to dispose or not. Instead, I am aware that circumstance by circumstance,
one can determine if a particular class should or shouldn't be disposed.
This is the best you are going to get, but you just won't accept that. And
when this answer is given, you just seem to scream a little louder at the
messenger about the message.

You know what? Some objects in the real world are dangerous if swallowed.
Can you please provide me with the complete list of those that are and those
that aren't?
 
I think this is where a large part of the disconnect between the two of us
in this conversation is. I'm trying to get answers about the use of Dispose
on existing classes built into the .NET Framework, and you're talking about
user-created classes. I keep trying to explain that this I'm not concerned
with user-created classes, but rather with the existing .NET classes, but
somehow I keep getting responses that are at best peripherally related to
the existing .NET classes.

Lay off the sarcasm? Like this, eh? "> Sorry if this keeps you up at
night."

God knows I'll definitely sleep better now.

Scott M. said:
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".
 
Scott M. said:
Well Michael, no offense to you, but I can do without your sarcasm and
seemingly personal attacks on me.

Nothing personal. But I could do without your generic answers directed at
me that relate to questions which I am not asking. As stated, I'm not
asking about user-created classes, yet I keep getting user-created class
hints, tips and answers. I'm not asking about broad generalities, but I
keep getting broad generalities.
Your question makes perfect sense, and it is reasonable to think that a
simple, clear concise answer should be given. But, you know what Michael?
The answer isn't simple. To me, it seems that you want to blame me (or
someone) because the simple, clear, concise answer you seek doesn't exist
in that form.

I am not aware of any complete text that lists the do's and don'ts of what
to dispose or not. Instead, I am aware that circumstance by circumstance,
one can determine if a particular class should or shouldn't be disposed.
This is the best you are going to get, but you just won't accept that.
And when this answer is given, you just seem to scream a little louder at
the messenger about the message.

The only problem I have with you, Scott, is that you keep answering the
wrong question. If you don't know the answer, I definitely won't hold it
against you, just say "I don't know the answer to the question you're
asking" and let someone else who might know take a shot at answering.
You know what? Some objects in the real world are dangerous if swallowed.
Can you please provide me with the complete list of those that are and
those that aren't?

So glad you asked!!! There are three "rules" in determining what to
swallow:

1) Never swallow anything
2) Swallow everything
3) Swallow only non-harmful things

Some people live by Rule #2, but I try to strive for Rule #3.

Hope that answered your question as well as you've answered mine!
 
Cor, please! READ MY POSTS before responding.

Did I say you used the word elaborate? No, I said you "seem to keep trying
to elaborate". Do you know what that means?
 
Lay off the sarcasm? Like this, eh? "> Sorry if this keeps you up at
night."

God knows I'll definitely sleep better now.

That wasn't sarcasm. That was the only conclusion I could come up with why
you seem to be taking your frustrations out on me. This is what I call
sarcasm:

"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". "
 
Nothing personal. But I could do without your generic answers directed at
me that relate to questions which I am not asking. As stated, I'm not
asking about user-created classes, yet I keep getting user-created class
hints, tips and answers. I'm not asking about broad generalities, but I
keep getting broad generalities.

You have every right to not respond to information you deem not related to
you. You do not have the right to be sarcastic and borderline mean to
people posting information in a public place with the best of intentions for
all to consume.
The only problem I have with you, Scott, is that you keep answering the
wrong question. If you don't know the answer, I definitely won't hold it
against you, just say "I don't know the answer to the question you're
asking" and let someone else who might know take a shot at answering.

Again, I gave you the answer (below), you just don't want to accept it.

[I am not aware of any complete text that lists the do's and don'ts of what
to dispose or not. Instead, I am aware that circumstance by circumstance,
one can determine if a particular class should or shouldn't be disposed.]
So glad you asked!!! There are three "rules" in determining what to
swallow:

1) Never swallow anything
2) Swallow everything
3) Swallow only non-harmful things

Some people live by Rule #2, but I try to strive for Rule #3.

Hope that answered your question as well as you've answered mine!

Ah but see, you didn't answer the question that "I was asking". See, I
didn't ask what you or other people eat, I asked for a complete list of what
is and isn't harmful to eat. So as soon as you get that list to me, I'll
get you the imaginary list you are looking for.
 
Scott M. said:
Again, I gave you the answer (below), you just don't want to accept it.

[I am not aware of any complete text that lists the do's and don'ts of
what
to dispose or not. Instead, I am aware that circumstance by circumstance,
one can determine if a particular class should or shouldn't be disposed.]

Of course I can readily accept the fact that you do not know this
information; however, you must accept the fact that someone else may know,
or at least be aware of good resources for finding, this specific
information.
Ah but see, you didn't answer the question that "I was asking". See, I
didn't ask what you or other people eat, I asked for a complete list of
what is and isn't harmful to eat. So as soon as you get that list to me,
I'll get you the imaginary list you are looking for.

Ah, now perhaps you understand my frustration with your "answers" to my
question. Perhaps not.

Like you, I didn't ask what you or other people Dispose, I asked for a
complete list of what should and should not be Disposed. Which should make
a much, much shorter list than items that can be swallowed. After all,
there are far more things that can be "swallowed" than there are built-in
classes in the .NET Framework that expose a Dispose method; however, as you
can see, your answers apply to this situation (and probably any other
situation you could possibly think up), without losing any of their
practical value.

Now, if you want to get into more practical detail, we could look at all
objects that expose a "Swallow" method. We can further refine the "list" to
"you will learn what not to swallow by experience" (you will learn when to
use Dispose by experience), "you can teach yourself advanced Chemistry and
Biology courses and perform chemical analysis on everything that has a
Swallow method" (after all you can learn IL and use ILDASM and Object
Browser to determine which objects to Dispose), you can follow the
Manufacturer's Recommendations for Swallowing - assuming there are any, and
make note of the exceptions. I can also tell you that it is correct to
swallow chocolate milk and chicken casserole based on their Swallow
interfaces. That's 2 down, how many to go?
 
Now *that* is an excellent tool to discover a baseline. Thank you.

IMHO, MS just needs to dedicate a person or two to documenting this and
letting people know when and how to use their product; rather than leaving
it to people to accidentally discover, or spend hours researching this when
they could be doing far more productive things. It would seem the next step
would be to determine if the Dispose and Disposable types use unmanaged
resources. Do you think there is a programmatic way to determine this?

Jay B. Harlow said:
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 C# said:
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.
 
Well, actually you didn't say that the first time,

Okay, let's see what I actually said...

Most commonly, there's an awful lot of objects that don't need to be
disposed at runtime but have a visual representation of themselves in
Visual Studio that *does* need to be disposed.

That's pretty straightforward. Some objects need runtime disposing, but
there's a lot of objects that don't, even if those objects might need
design-time disposing.

Originally you disagreed that this was even possible. Do you still hold
that opinion?

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.

An OleDbConnection isn't a web control.
And, gee, your sarcasm is something we can do without as well.

Perhaps you're right.
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?

Short answer: yes, you should dispose an OleDbConnection at runtime.*


* Longer answer, OleDbConnection is one of the most complex examples
there is. The problem is the subtle differences between Close and
Dispose on an OleDbConnection, and also the effect that Dispose and
FreeCoTaskMem can have on the connection pool and the interface with the
actual DB provider. In truth, I honestly don't know the answer
(although profiling seems to imply that it really doesn't matter much
either way). Mind you, you should definitely *Close* an
OleDbConnection, but Close and Dispose aren't the same thing, despite
what a lot of the docs say.
 
OK Got it. Learn IL, then use Object Browser and Reflector to observe the
objects...

Well, I actually think everyone should know IL anyway :)
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.

Dispose is a tough problem, I'm not disagreeing there. Ideally we'd
have automatic ref counting systemwide and deterministic finalization,
but the technology just isn't there yet.

OTOH, Dispose just isn't something I spend my days worrying about
(unlike C++, for example, where dangling references and object lifetimes
were a constant concern). A few simple ground rules get me through the
common objects, and if I screw up a bit, I feel pretty confident that
most objects I deal with will implement the Finalize/Dispose pattern
properly so it won't really hurt too much.

There are things I can rail against if I choose (the component model was
a terrible idea, IMHO), but in general I think MS made the right
trade-off with the GC and Dispose.
 
[I am not aware of any complete text that lists the do's and don'ts of
what
to dispose or not. Instead, I am aware that circumstance by
circumstance,
one can determine if a particular class should or shouldn't be disposed.]

Of course I can readily accept the fact that you do not know this
information; however, you must accept the fact that someone else may know,
or at least be aware of good resources for finding, this specific
information.

That's true. As someone who has worked with .NET since early beta, my
answer was based on what I have seen, heard and read. I believe that answer
to be correct. The list you seek does not exist. Up to you to do what you
want with that information, but it IS my answer to the specific question you
asked.
Ah, now perhaps you understand my frustration with your "answers" to my
question. Perhaps not.

Actually not since I did answer your direct question, you just don't wish to
acknowledge the answer. You, on the other hand, did not address my
question.
Like you, I didn't ask what you or other people Dispose, I asked for a
complete list of what should and should not be Disposed.

You know, I'd like you to tell me where my answer to your question was what
I personally Dispose or don't Dispose because you keep saying that I've
avoided your direct question and I keep telling you that this is not the
case. You and I have had 2 conversations going in this thread (1 about your
question and one about "splitting hairs" which is slightly off-topic). I
honestly believe that you have taken my posts about one and applied them as
responses to the other.
Which should make a much, much shorter list than items that can be
swallowed. After all, there are far more things that can be "swallowed"
than there are built-in classes in the .NET Framework that expose a
Dispose method; however, as you can see, your answers apply to this
situation (and probably any other situation you could possibly think up),
without losing any of their practical value.

The actual amount of items in the Framework are large enough and the
inheritance used to create them is intracate enough to make such a list an
improbability (if not an impossibility) which is the point of my analogy.
Now, if you want to get into more practical detail, we could look at all
objects that expose a "Swallow" method. We can further refine the "list"
to "you will learn what not to swallow by experience" (you will learn when
to use Dispose by experience),

Who said "you will learn when to use Dispose by experience"? That's not
what I said. I said "circumstance by circumstance,
one can determine if a particular class should or shouldn't be disposed"
"you can teach yourself advanced Chemistry and Biology courses and perform
chemical analysis on everything that has a Swallow method" (after all you
can learn IL and use ILDASM and Object Browser to determine which objects
to Dispose), you can follow the Manufacturer's Recommendations for
Swallowing - assuming there are any, and make note of the exceptions. I
can also tell you that it is correct to swallow chocolate milk and chicken
casserole based on their Swallow interfaces. That's 2 down, how many to
go?

Ah bravo! Now, you've finally got to the point. YES, what you have written
above IS the course one should take to know when to and when not to Dispose.
And so, the last thing I will say here (and leave you whatever last words
you like) is that with this last paragraph you have (wittingly or not and
like it or not) arrived at what I've been trying to tell you all along.
This is the answer to your question: there is no list! Use ILDASM, the
Object Browser, and whatever other tools available to investigate the
classes you work with and learn about them. Then, based on what you've
learned, you can make a much more informed decision about Dispose.

Good luck to you.
 
At this point, it is probably best that we just agree to disagree and go our
separate ways. And here I suppose I get the last word in, and my last word
is: Thank you.
 
Jay,

I did first your routine and than the way I normal do it, I did not push the
F11 enough, than I would have seen it.

Thanks,

Cor
 
Michael,
It would seem the next step would be to determine if the Dispose and
Disposable types use unmanaged resources. Do you think there is a
programmatic way to determine this?
Not really. However it might not provide you with what you want any way!

One Pattern/Recommendation (don't have the link handy, I can find it if you
like) is for your public class to define a private inner (nested) class that
contains (only manages) the unmanaged resource. Both classes Implement
IDisposable, however only the inner class implements Finalize. The public's
class Dispose delegates Dispose to an instance of the inner class.

This way only the small dedicated class is finalized, where as the bulkier
outer class will GC quicker. Normally this pattern would be used where you
have a class with a lot of managed instance fields, and only a single
unmanaged instance field.

Based on this thread I am revising my "rules" for when I don't call Dispose,
thus simplifying when I do call it. However! I have not flushed out the
entire list yet. When I get the list flushed out I will post it here. Note
it will be a list of rules similar to David's list (I believe it was
David's). Unfortunately it will not be a list by type! As I see little value
over time with a list by type! However if you accept the rules then creating
a list by type should be easy enough.

Hope this helps
Jay

Michael C# said:
Now *that* is an excellent tool to discover a baseline. Thank you.

IMHO, MS just needs to dedicate a person or two to documenting this and
letting people know when and how to use their product; rather than leaving
it to people to accidentally discover, or spend hours researching this
when they could be doing far more productive things. It would seem the
next step would be to determine if the Dispose and Disposable types use
unmanaged resources. Do you think there is a programmatic way to
determine this?

Jay B. Harlow said:
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 C# said:
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.

message 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


message 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 B. Harlow said:
Michael,
Not really. However it might not provide you with what you want any way!

One Pattern/Recommendation (don't have the link handy, I can find it if
you like) is for your public class to define a private inner (nested)
class that contains (only manages) the unmanaged resource. Both classes
Implement IDisposable, however only the inner class implements Finalize.
The public's class Dispose delegates Dispose to an instance of the inner
class.

This way only the small dedicated class is finalized, where as the bulkier
outer class will GC quicker. Normally this pattern would be used where you
have a class with a lot of managed instance fields, and only a single
unmanaged instance field.

Ugh. So the unmanaged resources could be hidden from prying eyes anyway?
Too bad there's not a public read-only Boolean attribute you could check to
see if an object *needs* to be Disposed of or not. Something like
".DisposeRequired" or some such, or even a flag indicating that it uses (or
might use) unmanaged resources to give you a better idea up front that yes
this should be Disposed.

I really don't like this idea of writing sub-optimal code until I encounter
a problem and realize that 'hey I should have Disposed of that', then fixing
it after the fact with a "service pack"-type remedy. I am taking the plunge
and learning IL (it can't be harder than x86 Assembler can it?) I don't
mind learning something new, but I don't like feeling like I'm being forced
to learn it by weaknesses in my chosen platform - or even worse - by
weaknesses in the documentation of my chosen platform.
Based on this thread I am revising my "rules" for when I don't call
Dispose, thus simplifying when I do call it. However! I have not flushed
out the entire list yet. When I get the list flushed out I will post it
here. Note it will be a list of rules similar to David's list (I believe
it was David's). Unfortunately it will not be a list by type! As I see
little value over time with a list by type! However if you accept the
rules then creating a list by type should be easy enough.

I have no problem accepting the rules, if they help me narrow down the focus
of the problem. Throwing out things like "'Appropriately' use Dispose" in
answer to the question of "How do I Appropriately use Dispose?" is basically
throwing the question back in the asker's face, and doesn't really narrow
the focus of the problem.

Thanks for your help on this!
 

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