views:

211

answers:

4

I recently came across this VerticalLabel control on CodeProject.

I notice that the OnPaint method creates but doesn't dispose Pen and SolidBrush objects.

Does this matter, and if so how can I demonstrate whatever problems it can cause?

EDIT

This isn't a question about the IDisposable pattern in general. I understand that callers should normally call Dispose on any class that implements IDisposable.

What I want to know is what problems (if any) can be expected when GDI+ object are not disposed as in the above example. It's clear that, in the linked example, OnPaint may be called many times before the garbage collector kicks in, so there's the potential to run out of handles.

However I suspect that GDI+ internally reuses handles in some circumstances (for example if you use a pen of a specific color from the Pens class, it is cached and reused).

What I'm trying to understand is whether code like that in the linked example will be able to get away with neglecting to call Dispose.

And if not, to see a sample that demonstrated what problems it can cause.

I should add that I have very often (including the OnPaint documentation on MSDN) seen WinForms code samples that fail to dispose GDI+ objects.

+1  A: 

The objects should be disposed of by the garbage collection after they've fallen out of scope as long as they're not referenced by anything else.

The simplest way to demonstrate whether this is happening or not (without making any code changes) is to use a large number of these controls on a form and see if the memory used by the application keeps growing or remains stable.

ChrisF
I understand that they'll eventually be GC'd, but when? I wouldn't expect memory to grow, rather the number of handles used. And to test all cases I'd need to be sure to be creating brushes/pens of different colors.
Joe
A: 

It's just leaking un-managed resources (the pen/brush) until the corresponding managed object is reclaimed by the garbage collector. So you're wasting a few handles that aren't used afterwards anymore.

It's not too big a deal because Finalize() will call Dispose() but releasing unmanaged resources should usually be done rather sooner than later.

Joey
Yes I understand that the GC will eventually kick in, but, since OnPaint can be called frequently, is there a risk that more than "a few" handles are "wasted".
Joe
Probably, yes. Depending on how much heap .NET will use and therefore it depends on how often the GC will kick in. However, an OnPaint method will likely only generate generation 0 objects that will be reclaimed more frequently.
Joey
Calling it "leaking" makes it sound wrong. I don't think it's wrong at all.
romkyns
+3  A: 

Of course it does matter. It is important to dispose all instances of classes that implement IDisposable when they are no longer needed. Classes are defined IDisposable when they make use of unmanaged resources, that is, operating system resources that are not handled by the .NET Framework.

If you don't manually dispose the objects, then these unmanaged resources will not be freed until the garbage collector invokes the object finalizer (and this will only happen if the class has properly implemented the Dispose pattern), which may be very late since the garbage collector only runs when it detects an actual memory shortage. Thus when not disposing objects, you are retaining operating system resources that could otherwise be used by other applications.

A discussion on this subject can be found here: http://agilology.blogspot.com/2009/01/why-dispose-is-necessary-and-other.html

Konamiman
My question isn't about the IDisposable pattern in general, I understand what it's for and why callers should generally call Dispose. See Edit to the question.
Joe
A: 

in addition i would tell that is preferable to use the ready collections: System.Drawing.Pens. and System.Drawing.Brushes. if you not customize them in a special way.

serhio
Yes I agree. But in the linked example, this isn't possible, because Pens and Brushes only contain elements for a fixed number of predefined colors.
Joe