简体   繁体   中英

VB.NET control GDI handle leak?

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

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.

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. ;)

If you'll continue to work with GDI-objects you can use some leak-detectors. If you use such program you'll see full stack which show where each object was created.

GDI objects count increase when you set label font. So, you can call the dispose method of that label and set font as null or nothing if you want to get rid of it. This is expected behavior.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM