Dispose Again!

  • Thread starter Thread starter Guest
  • Start date Start date
David said:
OK, a simple answer. Disposing a SqlCommand does absolutely nothing
except take up time. It's a no-op.

Thank you! Finally a straight answer! My next question is this: is the
optimizer smart enough to figure this out and discard the no-op?
I see your general point here, but in practice it's not that tough. In
day-to-day programming, I pretty much deal with only four types of
objects:

Web controls, which never need to be disposed.

Forms controls, which should always be disposed.

Data library objects, and since there's only a few of them I tend to
know the ones I'm working with pretty damn well since I'm hitting the db
all day long, and so I have a pretty good sense as to whether I want to
dispose them and when.

Things that derive from Component, which generally don't need to be
disposed, but it only takes a moment to figure out if the class actually
implements a Dispose function, so in practice that's not a problem.

Now see, this is where the confusion comes in. You say Forms controls
should always be disposed - yet others say Dispose is not necessary on a
Label... Is the Label an "exception"? Or should Forms controls, including
the Label, be disposed?

Also, at the end you mention "it only takes a moment to figure out if the
class actually implements a Dispose function..." which takes us full circle
to the crux of the matter - some say that not everything that implements a
Dispose needs to be Disposed. The question is which Components that expose
a Dispose method need to have Dispose called on them?
I actually think avoiding the Dispose calls makes code a lot cleaner.

That may be true, but I think it may be short-term thinking. Per another
message in here, if the SqlCommand, for instance, were to be implemented
differently in the future - and the Developer suddenly recommends the use of
Dispose - you will have to re-tool your design patterns and re-work your
code.
 
David said:
What's your point exactly? Are you implying that VS.Net *doesn't* need
to call Dispose on custom controls and components instantiated in
designers? Why not?

Well, see David, I think it goes back to the well-documented Third Rule
which states "Use Dispose() correctly"...

:)
 
OK, that makes more sense. You were showing the list of Component-derived
classes which require Dispose.
 
Has anyone from Microsoft itself weighed in on this, or are the MS-employed
Developers steering clear of this train wreck? I personally would like to
hear it from the horse's mouth once and for all.
 
Thank you! Finally a straight answer! My next question is this: is the
optimizer smart enough to figure this out and discard the no-op?

I don't see how, that's why it takes up (a little) time. There's a lock
and a few tests involved.
Now see, this is where the confusion comes in. You say Forms controls
should always be disposed - yet others say Dispose is not necessary on a
Label... Is the Label an "exception"? Or should Forms controls, including
the Label, be disposed?

In practice, it's really not an issue for me. I add it to components
and I know the components will be disposed for me. I realize there are
designs where this is a real issue, but so far it's just not an issue to
me.
Also, at the end you mention "it only takes a moment to figure out if the
class actually implements a Dispose function..." which takes us full circle
to the crux of the matter - some say that not everything that implements a
Dispose needs to be Disposed. The question is which Components that expose
a Dispose method need to have Dispose called on them?

I know what Component.Dispose does, and MarshallByRefComponent.Dispose, etc. So
the only issue is whether the class itself implements a needed Dispose
override, and that only takes a second to check.

That may be true, but I think it may be short-term thinking. Per another
message in here, if the SqlCommand, for instance, were to be implemented
differently in the future - and the Developer suddenly recommends the use of
Dispose - you will have to re-tool your design patterns and re-work your
code.

And I do worry about that, but there's a flipside. I see a lot of code
that does a premature Dispose that only works because Dispose doesn't
really do anything. If some class I'm calling suddenly implement a
truly destructive dispose, my code might have a few temporary leaks but
that's better than simply crashing. And I do somewhat trust that decent
programmers will implement Finalize correctly.

I'm not saying this is right, just that it's a trade-off. Dispose is
basically a hole in the Framework due to (necessary) limitations of the
GC. I don't think there's a simple one-size-fits-all solution to it.
 
Michael,
The bottom line is that you have given no substantial reason to waste time
researching and categorizing when to call, and when not to call, Dispose()
on classes that expose it.
Exactly!!!!!

I have not given a substantial reason as IMHO there is no substantial
reason! I believe I stated (at least implied) I would not waste time
researching & categorizing when to call or not call Dispose.

As JD, David & myself have tried to state: We work with a certain set of
classes, by experience we have learned which need to be disposed & which do
not.
As for learning the inner workings of classes in the .NET Framework, I
I don't believe I stated inner workings, I definitely did not mean to imply
inner workings, as I consider inner workings as implementation details that
are subject to change. What I intended on stating is that you need to learn
the "intent" or the workings of the class! I hope you agree that learning
the intent of a class is important before you just start "throwing code
together".

Hope this helps
Jay
 
David said:
In practice, it's really not an issue for me. I add it to components
and I know the components will be disposed for me. I realize there are
designs where this is a real issue, but so far it's just not an issue to
me.

This wasn't an issue for me either, until I was informed that I was wrong.
This is another item that I don't have time to waste contemplating theory
versus practice. I'll just let the Forms Designer generated code handle the
Dispose's on Forms controls and call it a day.
I know what Component.Dispose does, and MarshallByRefComponent.Dispose,
etc. So
the only issue is whether the class itself implements a needed Dispose
override, and that only takes a second to check.

This is the information I need! How do you determine if a class implements
a *needed* Dispose override, as opposed to an unnecessary one? So far I've
been given the run-around on this particular question with a lot of
inadequate answers. If I could get a solid definitive answer on this one
question, it would pretty much answer everything. It seems you have to
"know the secret 'Brotherhood of Le Architects' handshake" in order to get
this one particular piece of information.
And I do worry about that, but there's a flipside. I see a lot of code
that does a premature Dispose that only works because Dispose doesn't
really do anything. If some class I'm calling suddenly implement a
truly destructive dispose, my code might have a few temporary leaks but
that's better than simply crashing. And I do somewhat trust that decent
programmers will implement Finalize correctly.

That makes sense, although I haven't encountered that problem to date - and
I'd think that a destructive Dispose would make itself known via crashing,
etc., far before the product made its way out of development. But stranger
things have happened I suppose. How much of a memory leak you're willing to
tolerate probably depends on a lot of factors, I would imagine.
I'm not saying this is right, just that it's a trade-off. Dispose is
basically a hole in the Framework due to (necessary) limitations of the
GC. I don't think there's a simple one-size-fits-all solution to it.

I think the best solution, from my point of view, would be better
information about when - and when not - to call it. As of now it seems like
quite a hindrance.
 
"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, 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!
 
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.
 
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
 
Your saying that the purpose of Dispose on components is for VS.NET's sake
and not for the running application's sake because VS.NET is causing the
component to hold on to unmanaged resources. What unmanaged resources does
a label or textbox hold on to that VS.NET must dispose of?

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. That is what I take issue with, that is what is completely false.

Dispose does not exist as some sort of clean up tool for VS.NET.
 
Jay B. Harlow said:
Michael,
Exactly!!!!!

I have not given a substantial reason as IMHO there is no substantial
reason! I believe I stated (at least implied) I would not waste time
researching & categorizing when to call or not call Dispose.

As JD, David & myself have tried to state: We work with a certain set of
classes, by experience we have learned which need to be disposed & which
do not.

So basically, a beginning programmer can expect to put out potentially
problematic, sub-optimal code full of memory leaks until they learn [by
experience alone??] "which need to be disposed & which do not." That's
definitely a sub-optimal answer.
I don't believe I stated inner workings, I definitely did not mean to
imply inner workings, as I consider inner workings as implementation
details that are subject to change. What I intended on stating is that you
need to learn the "intent" or the workings of the class! I hope you agree
that learning the intent of a class is important before you just start
"throwing code together".

I apologize if I misunderstood your statement that "However the System.Data
namespace I took the time to *learn* (rather then simple research) how the
DataSet object model actually works." As for the "intent", perhaps you
could explain further? I'm sure you don't mean by "intent" that the
"SqlConnection" class has the "intent" of allowing you to connect to a SQL
Server database. Or that the "Label" class has the "intent" of displaying
text. If this is the "intent", I'm sure MSDN Online is more than adequate
in detailing it. If "intent" is rather some arcane bit of trivia pertaining
to particular methods of a particular class...
 
This is the information I need! How do you determine if a class implements
a *needed* Dispose override, as opposed to an unnecessary one? So far I've
been given the run-around on this particular question with a lot of
inadequate answers.

Personally, I just pull up Reflector (or even ildasm) and look at the
class. IL is pretty readable. Often, component-derived classes don't
even implement Dispose, it's just there from the base class.
That makes sense, although I haven't encountered that problem to date - and
I'd think that a destructive Dispose would make itself known via crashing,
etc., far before the product made its way out of development.

Well, that assumes we're in development. For example, I tend to load a
lot of things through reflection, so I can't really be sure what I'm
getting during development is what I'm getting in production.

But for the most part, we're probably talking about a new version of
..NET, and for that I expect major dispose changes to be fairly well
known (if not documented by MS, they'll still show up on mailing lists,
etc.).
But stranger
things have happened I suppose. How much of a memory leak you're willing to
tolerate probably depends on a lot of factors, I would imagine.


I think the best solution, from my point of view, would be better
information about when - and when not - to call it. As of now it seems like
quite a hindrance.

Agreed. For example, here's a nagging question. If I don't dispose an
IDbConnection, am I holding onto resources too long? But if I do
dispose it, what effect does that have on the connection pool
(presumably the pool can't reuse a Disposed connection, right?).

There's really no way to answer that without knowing the internals of
the class, but the whole point of using the interface (instead of a
concrete class) in the first place was so that my code didn't have to
know the internals of the class.

That's a problem I still haven't figured out a decent answer to.
 
Your saying that the purpose of Dispose on components is for VS.NET's sake
and not for the running application's sake because VS.NET is causing the
component to hold on to unmanaged resources. What unmanaged resources does
a label or textbox hold on to that VS.NET must dispose of?

Quite often, a visual representation of itself which might consume GDI
resources. Database objects tend to hold onto a connection to the
database. More to the point, there's no way for VS.NET to know what
unmanaged resources the object is holding onto.
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.

I'm saying that's true in some cases.
That is what I take issue with, that is what is completely false.

Well, gee, it's hard to argue with that impeccable logic. And you've
backed up your argument so well here with, well, pretty much nothing.
Dispose does not exist as some sort of clean up tool for VS.NET.

Dispose exists as, essentially, a clean up mechanism for consumers of a
class. VS.Net is one such consumer. VS.Net also has special needs at
design-time, that's exactly why there's a mechanism for classes to know
whether they're running under a design-time environment, so that they
can alter their behavior in that environment. Some objects need
different Dispose behavior depending on their environment.

This really isn't complex or controversial stuff. It's pretty basic.
 
doh,

Jay,

Forget it, this I have long ago checked with debugging, it is done by the
close. I became confused by this discussion.

Cor
 
Doh!
are subject to change. What I intended on stating is that you need to
learn the "intent" or the workings of the class!
That should read "the "intent" or outer workings of the class

Jay
 
Michael,
This is the information I need! How do you determine if a class
implements a *needed* Dispose override, as opposed to an unnecessary one?
So far I've
In addition to the list of class members in MSDN Online & ILDASM or
Reflector that David mentions, you can use Object Browser in VS.NET.

Jay
 
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:
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.

Yes yes, I think you're confusing the horse's orifices again. Is this *all*
that the documentation says? This is a great, nice, wonderful sound bite,
and I'm sure it's just dandy if you're developing your own class which uses
unmanaged resources.

Now, which of the classes built into the .NET Framework "use unmanaged
resources", and which don't? Simple question right?
 

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