views:

899

answers:

2

I have a problem with a control leaking GDI handles. This is the cut-down version of the control:

Public Class FancyLabel
    Inherits Label

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
     e.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
     MyBase.OnPaint(e)
    End Sub

End Class


When I run the program, the GDI object count is 38.

Then I open a form that has only one FancyLabel on it and the GDI object count gets increased to 42.

I then close the form and the GDI count falls down to 39 and stays there no matter how many instances of the form I create and close.

Any Ideas?

Thanks JV

A: 

Well the GDI count could be increasing due to windows forms. Windows forms indirectly uses GDI when the system is rendering some controls. You can use .NET Memory Profiler to find out where the leak is and determine how to solve it.

EDIT: GDI objects are not automatically picked up by the Garbage Collector. You should override the Dispose method and ensure all GDI objects are disposed of properly.

Russ Bradberry
There are no other controls on the form. If I replace the FancyLabel with just the ordinary System.Windows.Forms.Label, everything works as expected, ie. the final GDI count is back to 37 after I close the form.
edited for more info
Russ Bradberry
"GDI objects are not automatically picked up by the Garbage Collector. You should override the Dispose method and ensure all GDI objects are disposed of properly."Yes, I agree, but as you can see, I'm not creating a GDI object anywhere, I'm just changing an enumeration value on existing Graphics object.That is the part that confuses me...
+1  A: 

So if you continue the process you described 100 times in a row, I assume the GDI count would go no higher than 39?

If so, this may be something you'll have to live with. The GDI objects necessary for your FancyLabel are not something that .NET exposes directly. I think the best you can do is dispose the controls that contain the GDI objects at every opportunity. But in your case, it sounds like your leak is not so bad and probably not worth the trouble.

It's the leaks that continue to build up and consume GDI objects with repeated use that you really need to look out for. Just for kicks, the GDI object types are listed here. This reference doesn't have a direct correllation to Windows Forms controls, but you can sort of imagine what some controls might be using (and I'm sure that's documented elsewhere).

Fortunately, Microsoft has finally gone away from GDI objects with WPF. A pure WPF application will only use 2 GDI objects for the window itself (the rest of the UI is GDI-free). So if you're just at the beginning stages of the project you're working on, perhaps now is a good time to consider WPF instead. ;)

Steve Wortham
I agree. If adding 10 FancyLabels causes the count to go no higher than 39, your control isn't really leaking; something else is going on.
OwenP