Clean up after yourself!

  • Thread starter Thread starter Eric Cadwell
  • Start date Start date
E

Eric Cadwell

A handy piece of code...

Put this in your Dipose() methods and it will do all your clean up for.
Just need to add support for unregistering events and all our memory leaks
will be gone!

public void Disposer()
{
Type type = this.GetType();
if (type != null)
{
foreach(FieldInfo fi in type.GetFields(BindingFlags.NonPublic |
BindingFlags.Instance))
{
object field = fi.GetValue(this);
if (field is IDisposable)
{
((IDisposable)field).Dispose();
Console.WriteLine("disposed field:" + fi.Name);
}
}
}
}

Eric Cadwell
http://www.origincontrols.com
 
Hi Eric!

Thanks for this piece of code... I'll use it well! :)
Two question though... do you have any examples of unregistering events in
this contex?
Does this method slow down the application?

Thanks,
saso
 
Yes, but remember that you have to call the method :-)

If you implement the C# destructor (Finalize) to callk your Dispose method,
then you have another issue - if your fields are objects that have
finalizers then they'll be queued to be finalized too, and maybe finalized
before your object's Destructor (Finalize) is called.

This is why components implement a protected version of Dispose that takes a
bool parameter. This parameter has a value of false if the method is called
by the finalizer and true if it is called by the publicly accessible
IDisposable.Dispose. If the parameter is true then both managed and
unmanaged objects should be disposed, if it is false then only unmanaged
objects should be disposed.

Note that your code will not prevent memory leaks because you are disposing
managed objects and managed objects that hold resources should be disposable
and will have a finalizer as a safety measure so that when a GC occurs the
resources are released. The biggest source of leaks is from unmanaged
objects, which your code does not release.

Richard
 
The biggest issue I've found are event subscriptions to static (root)
objects. It happens within the framework code (i.e. DateTimePicker) and I
even recreated the same mistake in my code. The event registration prevents
all objects from being disposed. In this case, the object is never put in
the finalization queue because it believes the object is still in use base
on the implicit root reference. In such a case managed and unmanaged
resources are being leaked unless I manually invoke Dispose on everything
(which at best allows the unmanaged resource to be reclaimed). On that note,
it's much cleaner to run my function than to embed explicit calls for each
object instance in the Dispose() method.

If I could enhance that sample to delete event registrations and nullify the
reference it would go a long way to improve performance.

-Eric
 
Back
Top