Dispose or not??

  • Thread starter Thread starter qrli
  • Start date Start date
Q

qrli

I used to think that all objects that implement
IDisposable should be disposed. But I found 80% of the
classes implement IDisposable.

But when I looked into the samples, most objects are not
disposed. Generally, they're Gdi objects, form controls,
most components, etc.

So why? How can I decide to dispose or not?
 
Hi,

In most cases you don't have to call dispose method explicitly. The garbage
collector will dispose all unreachable object without puasing the interface.
C# GC manages them well, so most of these sample, you have refered have let
GC to mange it.

Nirosh.
 
Unless an object's class asks you to explicitly call Dispose, you don't have
to. The GC will take care.

Most GDI objects require you to call Dispose - to release their handle
internally.

vJ
 
qrli said:
I used to think that all objects that implement
IDisposable should be disposed. But I found 80% of the
classes implement IDisposable.

80%? Where do you get that figure? That sounds awfully high to me.
But when I looked into the samples, most objects are not
disposed. Generally, they're Gdi objects, form controls,
most components, etc.

Form controls will usually be disposed by the default code created by
VS.NET.
So why? How can I decide to dispose or not?

I would encourage you to always make sure you dispose of objects which
implement IDisposable.
 
Champika Nirosh said:
In most cases you don't have to call dispose method explicitly. The garbage
collector will dispose all unreachable object without puasing the interface.
C# GC manages them well, so most of these sample, you have refered have let
GC to mange it.

That's a bad idea though, as most types which implement IDisposable
either contain other IDisposables or directly contain native system
resources. Leaving those to the garbage collector (which only knows
about memory pressure, not Windows handle pressure etc) is a bad idea.
 
Vijaye Raji said:
Unless an object's class asks you to explicitly call Dispose, you don't have
to. The GC will take care.

The GC will do it at *some* point, but the very fact that a type
implements IDisposable means it's telling you that it would be
preferable to call Dispose explicitly.
 
Most classes in the following namespaces implement
IDisposable. And they're what I use most.
System.ComponentModel
System.Drawing
System.Windows.Forms

The code VS.NET generated doesn't dispose any thing
except Timer and ImageList. Only Timer and ImageList,
that is those have a constructor take an IContainer
parameter, are added to the components field and are
disposed in the Form.Dispose(bool).
 
Most classes in the following namespaces implement
IDisposable. And they're what I use most.
System.ComponentModel
System.Drawing
System.Windows.Forms

They may be what you use most when doing GUI stuff, but that's very
different from 80% of classes implementing IDisposable.
The code VS.NET generated doesn't dispose any thing
except Timer and ImageList. Only Timer and ImageList,
that is those have a constructor take an IContainer
parameter, are added to the components field and are
disposed in the Form.Dispose(bool).

It *does* dispose things - just not where you can see them. To
demonstrate this, create a simple form with just a label in it. Go into
the code and change it from creating a label to creating a MyLabel, and
define the MyLabel class as:

class MyLabel : Label
{
protected override void Dispose(bool disposing)
{
MessageBox.Show("Disposing: "+disposing);
base.Dispose (disposing);
}
}

Run it, and close the form - you'll see a message box saying
"Disposing: true" which shows that Dispose has been called.
 
That just proves that all objects are disposed when the
program shut down.

I can give you another example. In the D3D9 Wizard
generated code, D3DSettingForm was created and there's no
Dispose call.
 
qrli said:
That just proves that all objects are disposed when the
program shut down.

No - it's when the form itself is disposed (which it is automatically
on closing). To verify this, you could also do:

new Form1().Dispose(); // Or whatever your form is called

- and again, Dispose is called on all the controls added to it.
I can give you another example. In the D3D9 Wizard
generated code, D3DSettingForm was created and there's no
Dispose call.

Does D3DSettingsForm definitely not call Dispose internally when it's
closed though? I don't have the Managed DirectX SDK installed, but I
suspect it works the same way as the normal System.Windows.Forms does.
 
see below
No - it's when the form itself is disposed (which it is automatically
on closing). To verify this, you could also do:

new Form1().Dispose(); // Or whatever your form is called

- and again, Dispose is called on all the controls added
to it.

How to explain why ONLY Timer and ImageList are so
special that they must be added to components and
disposed explicitly if the form disposes all things
implicitly?

And again, why all samples in MSDN do not dispose GDI
objects?

I have a guess that rich resource objects can be left to
GC, e.g. GDI+ objects (32bit has not the former 16 bit
limit), Window Handles.
Does D3DSettingsForm definitely not call Dispose internally when it's
closed though? I don't have the Managed DirectX SDK installed, but I
suspect it works the same way as the normal
System.Windows.Forms does.

It's not disposed when closed, because I can access all
the properties and methods, even ShowDialog() again.
 
qrli said:
How to explain why ONLY Timer and ImageList are so
special that they must be added to components and
disposed explicitly if the form disposes all things
implicitly?

Presumably because they don't get added to the form in quite the same
way - they're not actually controls, so they won't go into a list of
controls that the form keeps around.
And again, why all samples in MSDN do not dispose GDI
objects?

That's probably just bad samples. There are some real stinkers in
there, to be honest.
I have a guess that rich resource objects can be left to
GC, e.g. GDI+ objects (32bit has not the former 16 bit
limit), Window Handles.

I don't think that's a good idea, no.
System.Windows.Forms does.

It's not disposed when closed, because I can access all
the properties and methods, even ShowDialog() again.

That doesn't *necessarily* mean it's not disposed, although it suggests
it. Could well just be that the DX9 stuff isn't written quite as well
as the Windows.Forms stuff. That isn't a good excuse for not calling
Dispose in your own code.
 
Hmm.. so, we really have to call Dispose on pretty much all user-created
objects (since most of them derive from IDisposable). That's good to
know...

Just curious - why couldn't they have made GC call Dispose when it cleans up
the object (if it implements IDisposable)?

Thanks,
vJ
 
Vijaye Raji said:
Hmm.. so, we really have to call Dispose on pretty much all user-created
objects (since most of them derive from IDisposable). That's good to
know...

No, you don't - because by the sounds of it, most objects which you're
creating are being placed on forms, and as I've said before, they're
disposed automatically when the form itself is disposed.

I rarely have to call Dispose (in fact I very very rarely call it
directly - I usually just have a using(...) block) apart from when I'm
using streams/readers/database objects.
Just curious - why couldn't they have made GC call Dispose when it cleans up
the object (if it implements IDisposable)?

Well, it calls the finalizer, which will usually call Dispose itself.
The point of calling Dispose explicitly is to make it happen in a
timely manner - there's no guarantee about when the GC will get round
to cleaning up.
 
Jon Skeet said:
Presumably because they don't get added to the form in quite the same
way - they're not actually controls, so they won't go into a list of
controls that the form keeps around.

This is correct. In Control.Dispose(bool), the .Net Control class calls
Dispose on all controls in the Control.Controls collection. This only occurs
within the branch of Dispose taken when it is not called from a Finalizer.
As Jon says, the Timer and ImageList are not controls, so they cannot be
places in the Control.Controls collection, and hence the base Control class
cannot take care of disposing them for you. This is why the template used by
VS for a Windows Form generates a components collection and a dispose for
the Form that will ensure the components collection is disposed as well.

I don't think that's a good idea, no.

It's a performance hit for starters. If you leave the controls to the GC,
you guarantee that you will have to wait longer for the resources to be
free, as well as for the memory of the objects themselves to be freed. This
is because it takes two rounds of the GC to fully collect a finalizable
object. Component.Dispose uses GC.SuppressFinalize, so disposing a Control
ensures that it will be collected in one GC, not two.

This means a non-disposed control is very likely to end up in Gen 2, which
is only rarely collected. So a non-disposed control can take significantly
longer to be collected than a disposed one, and hence any objects directly
or indirectly referenced by the control will take longer as well.

Niall
 
Back
Top