Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I need to call Dispose() on managed objects?

I can't believe I'm still confused about this but, any way, lets finally nail it:

I have a class that overrides OnPaint to do some drawing. To speed things up, I create the pens, brushes etc before hand, in the constructor, so that OnPaint does not need to keep creating and disposing them.

Now, I make sure that I always dispose of such objects, but I have the feeling I don't need to because, despite the fact they implement IDisposable, they're managed objects.

Is this correct?


Thanks for all the answers, the issue has certainly been nailed.
I'm glad I've been vigilant in always using 'using' so that I don't need to go through all my code checking. I just wanted to be clear that I wasn't being a pointless user.

As an aside, I did have a strange situation, recently, where I had to replace a using block and manually call dispose! I'll dig that out and create a new question.

like image 794
Jules Avatar asked Mar 30 '10 20:03

Jules


People also ask

When should you call Dispose?

There is a simple guideline: if you have finished with an object whose type implements IDisposable then call Dispose() on it; you should use a using block to do this.

Is Dispose automatically called?

Dispose() will not be called automatically. If there is a finalizer it will be called automatically. Implementing IDisposable provides a way for users of your class to release resources early, instead of waiting for the garbage collector.

How do I call a Dispose method?

The Dispose() methodThe Dispose method performs all object cleanup, so the garbage collector no longer needs to call the objects' Object. Finalize override. Therefore, the call to the SuppressFinalize method prevents the garbage collector from running the finalizer. If the type has no finalizer, the call to GC.

Do you need to Dispose C#?

In a way, C# objects are a lot like objects that are created using new syntax in C++ - they are created on the heap but unlike C++ objects, they are managed by the runtime, so you don't have to worry about destructing them.


1 Answers

It is not correct. You need to dispose objects that implement IDisposable. That is why they implement IDisposable - to specify the fact that they wrap (directly or indirectly) unmanaged resources.

In this case, the unmanaged resource is a GDI handle, and if you fail to dispose them when you are actually done with them, you will leak those handles. Now these particular objects have finalizers that will cause the resources to be released when the GC kicks in, but you have no way of knowing when that will happen. It might be 10 seconds from now, it might be 10 days from now; if your application does not generate sufficient memory pressure to cause the GC to kick in and run the finalizers on those brushes/pens/fonts/etc., you can end up starving the OS of GDI resources before the GC ever realizes what's going on.

Additionally, you have no guarantee that every unmanaged wrapper actually implements a finalizer. The .NET Framework itself is pretty consistent in the sense that classes implementing IDisposable implement it with the correct pattern, but it is completely possible for some other class to have a broken implementation that does not include a finalizer and therefore does not clean up properly unless Dispose is called explicitly on it. In general, the purpose of IDisposable is that you are not supposed to know or care about the specific implementation details; rather, if it's disposable, then you dispose of it, period.

Moral of the story: Always dispose IDisposable objects. If your class "owns" objects that are IDisposable, then it should implement IDisposable itself.

like image 161
Aaronaught Avatar answered Nov 08 '22 06:11

Aaronaught