How critical is it to call Dispose()

C

chak

How critical is it to call Dispose() of a class which implements
IDisposable(). Though it may be recommended as a good practise, which
situations make it very important ?

Regards,

Chak.
 
K

Kevin Spencer

It's very important if you app allocates a lot of memory in a short amount
of time, and if you use a lot of the type of class you don't want to Dispose
for some reason. It's also important if you're not sure the class implements
Dispose correctly. Microsoft implements it correctly, but not everyone else
does.

It's always a good idea to call it.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
A brute awe as you,
a Metallic hag entity, eat us.
 
N

Nick Hounsome

chak said:
How critical is it to call Dispose() of a class which implements
IDisposable(). Though it may be recommended as a good practise, which
situations make it very important ?

If you don't call Dispose() (or use the using statement) then you MAY run
out of resources or prevent others from accessing files or pretty well
anything else depending on the object.

IF your object becomes garbage and IF/WHEN the GC collects it it will call
the Finalize method which should release the resources anyway.

If you retain a reference to the object (and it's easy to do so by accident)
then the files opr whatever will never be released.

If you don't retain a reference there is no gaurantee when or even if the GC
will run. Usually you will probably get away with it but it would be totally
unacceptable in a commercial library.
 
G

Guest

If you attach to any unmanaged resources, it is critical. This includes those
down in the call stack that you did not call yourself (i.e., those that are
called by the .NET Framework components). Unless you are going to do a full
stack walk and ensure there are no components lower down the stack, I would
call Dispose() 100% of the time.

--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

***************************
Think Outside the Box!
***************************
 
G

Guest

How critical is it to call Dispose() of a class which implements
IDisposable(). Though it may be recommended as a good practise, which
situations make it very important ?

1. It is playing by the rules, so you should do it. Failing to dispose may
work today but fail tomorrow after a .net upgrade without any changes to your
code. Honor your oop contracts and genuflect often and peace shall be upon
you.

2. Some (fxcop, purists) say always dispose your IDisposables. Hmmm.
There are classes that implement IDisposable that also provide a documented
alternative. For example, WebResponse provides the Close method, so I Close
and I do not Dispose just like the MS provided samples and documentation
indicate. That seems reasonable provided you don't go overboard with
contract waivers.

3. I go overboard. My general approach to .net development is to follow
the examples and add dispose when I get into trouble. I detest the concept
and implementation of IDisposable. I feel better now.

4. Dispose is least important at app shutdown. When I shut down my apps, I
don't worry about disposing unless I know about an open file or something
like that.

5. Dispose is most important when you instantiate-destroy repeatedly and
dispose is actually necessary to prevent a memory leak. For example,
System.Windows.Forms.MainMenu
will leak if you instantiate MainMenu repeatedly and fail to dispose.
Sorry, I don't have a list of classes that have this behavior. Even if I
did, it may be valid today and not valid tomorrow, so you should always
dispose (or equivalent) your IDisposables. Amen.
 
B

Bruno Jouhier

Two potential problems (at least) if you don't call Dispose:

1) you may exhaust unmanaged resources (memory, handles, etc.) because the
GC does not know about these resources. So, if it does not run quickly
enough, you run into problems. Also, you put more load on the GC because the
IDisposable objects go through the finalizer queue in this case (Dispose, if
correctly implemented, removes them from the finalizer queue).

2) you lock unmanaged resources for an unpredictable amount of time. For
example, if you don't Dispose a Stream on an open file, the file remains
open and you won't be able to open it again until the GC collects the
Stream. Sometimes you will be lucky and your program will work ok, but
sometimes the second open will fail.

Morale: follow the guidelines and call Dispose (or better, use the "using"
construct if you are in C#).

Bruno
 
M

Michael.Suarez

So lets say I have

public int myMethod()
{
int myInt = 0;
string myString = new string();
SqlCommand cmd = new SqlCommand();
MyClass myVar = new MyClass();

//some code

return 0;
}


By saying that you should always call Dispose, wouldn't that mean you
should have:
myInt.Dispose();
myString.Dispose();
cmd.Dispose();
myVar.Dispose();

between //some code and the return statement?

i mean an int takes up so little space, so this might be overkill...
but where do you draw the line?
 
B

Bruno Jouhier

You should read the basic docs on Dispose() first.

Dispose() only exists in classes that implement the IDisposable interface.
Usually, these classes are classes that reference directly or indirectly
unmanaged resources.
Also, the intent of Dispose is *not* to free managed memory (the GC does it,
and there is no other way), it is to free the unmanaged resources in a
deterministic way.

Then:
myInt.Dispose(); // nonsense: does not compile, System.Int32 does not
implement IDisposable
myString.Dispose(); // idem
cmd.Dispose(); // YES, SqlCommand implements IDisposable.
myVar.Dispose(); // Only if MyClass implements IDisposable.

And the preferred way to write myMethod() is:


public int myMethod()
{
int myInt = 0;
string myString = "some string"; // new string(); does not compile!
using (SqlCommand cmd = new SqlCommand())
{
MyClass myVar = new MyClass();
//some code
}
return 0;
}

Bruno
 
J

Jeff Louie

I would argue that you should not rely on calling Dispose at all, but
use the
using construct which is exception safe.

Regards,
Jeff
 
K

Kevin Spencer

I would argue that you should not rely on calling Dispose at all, but
use the
using construct which is exception safe.

This is a useful practice, but not always. There are times when the lifetime
of a disposable object extends far beyond what is useful (or even possible)
to put into a using block.

A using block is simply a convenience for making sure that Dispose is
called. It is not a substitute for being aware that Disposable instances
should always be disposed.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
A brute awe as you,
a Metallic hag entity, eat us.
 
M

Michael.Suarez

So SqlCommand, DataSet, DataTable, DataAdapter all implement
IDisposable.

Let's say I have a function that uses an object for each one of these
classes, and all 4 of the objects are created & instantiated within the
function, and no longer needed once the function returns what it needs
to return.
If I don't dispose of them myself, the GC will eventually get rid of
them.
If I do dispose of them (either via the using statement, or calls to
Dispose()), then that's a few (not a lot, but at least 4) extra lines
of code.
So is it recommended for me to dispose of all 4 objects myself? or is
it overkill? at what point does it become overkill to just dispose of
every object you use?
 
B

Bruno Jouhier

So SqlCommand, DataSet, DataTable, DataAdapter all implement
IDisposable.

Let's say I have a function that uses an object for each one of these
classes, and all 4 of the objects are created & instantiated within the
function, and no longer needed once the function returns what it needs
to return.
If I don't dispose of them myself, the GC will eventually get rid of
them.

Yes, but you cannot predict when (unless you call GC.Collect() yourself,
which is not recommended).

Also, this is more costly because the objects have to go through the
finalizer queue of the GC. If you dispose them explicitly, their
finalization is inhibited and the GC performs better.
If I do dispose of them (either via the using statement, or calls to
Dispose()), then that's a few (not a lot, but at least 4) extra lines
of code.

With the "using" construct, that's very little extra code. If you allocate
several resources in a row, you can even group the using clauses and create
a single bloc:

using (Resource1 res1 = CreateResource1())
using (Resource2 res2 = CreateResource2())
using (Resource3 res3 = CreateResource3())
{
// do something useful
}
So is it recommended for me to dispose of all 4 objects myself? or is
it overkill? at what point does it become overkill to just dispose of
every object you use?

No, this is not overkill, this is strongly recommended.

On the other hand, you should not introduce IDisposable interfaces and
finalizers everywhere (which is what many people seem to think when they see
this feature). You only need to worry about IDisposable and finalizers if
the class references UNMANAGED resources.
 
M

Michael.Suarez

Thank you very much for taking the time to explain it. I like the tip
about having several usings and a single block... much cleaner than
having several usings with several sets of {}'s and your code tabbed
all the way over to the right side of the screen. Definately a very
useful tip. Thanks.

The main points I should take away (if i understand you correctly).
-if it implements IDisposable, and I am done with it, call dispose (or
use using). always.
-if i have my own class, only make it implement IDisposable if it is
going to access unmanaged resources.
 
B

Bruno Jouhier

-if i have my own class, only make it implement IDisposable if it is
going to access unmanaged resources.

If what you mean by "going to access unmanaged resources" is "references
unmanaged resources through one of its fields", yes.
But if the class accesses unmanaged resources temporarily and does not keep
references to them, there is no need to make it implement IDisposable.

Bruno
 

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


Top