简体   繁体   English

VB.NET控件GDI处理泄漏?

[英]VB.NET control GDI handle leak?

I have a problem with a control leaking GDI handles. 我有一个控件泄漏GDI句柄的问题。 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. 当我运行程序时,GDI对象计数为38。

Then I open a form that has only one FancyLabel on it and the GDI object count gets increased to 42. 然后,我打开一个只有一个FancyLabel的表单,GDI对象计数增加到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. 然后,我关闭该表单,无论创建和关闭多少个表单实例,GDI计数都会降至39,并保持在那里。

Any Ideas? 有任何想法吗?

Thanks JV 谢谢合资

Well the GDI count could be increasing due to windows forms. 好吧,由于Windows窗体,GDI计数可能会增加。 Windows forms indirectly uses GDI when the system is rendering some controls. 系统呈现某些控件时,Windows窗体间接使用GDI。 You can use .NET Memory Profiler to find out where the leak is and determine how to solve it. 您可以使用.NET Memory Profiler找出泄漏所在,并确定如何解决泄漏。

EDIT: GDI objects are not automatically picked up by the Garbage Collector. 编辑:垃圾收集器不会自动拾取GDI对象。 You should override the Dispose method and ensure all GDI objects are disposed of properly. 您应该重写Dispose方法,并确保正确处置所有GDI对象。

So if you continue the process you described 100 times in a row, I assume the GDI count would go no higher than 39? 因此,如果您连续进行100次描述的过程,那么我认为GDI计数不会超过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. FancyLabel必需的GDI对象不是.NET直接公开的对象。 I think the best you can do is dispose the controls that contain the GDI objects at every opportunity. 我认为您能做的最好的就是在每一个机会处都放置包含GDI对象的控件。 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. 您确实需要注意的是,泄漏会继续累积并消耗重复使用的GDI对象。 Just for kicks, the GDI object types are listed here . 仅用于踢球, 此处列出了GDI对象类型。 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). 此参考与Windows Forms控件没有直接关系,但是您可以想象一下某些控件可能正在使用什么(并且我确定在其他地方都有说明)。

Fortunately, Microsoft has finally gone away from GDI objects with WPF. 幸运的是,Microsoft终于使用WPF摆脱了GDI对象。 A pure WPF application will only use 2 GDI objects for the window itself (the rest of the UI is GDI-free). 一个纯WPF应用程序将仅对窗口使用2个GDI对象(UI的其余部分不包含GDI)。 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. 因此,如果您只是处于项目的开始阶段,那么现在也许是考虑使用WPF的好时机。 ;) ;)

If you'll continue to work with GDI-objects you can use some leak-detectors. 如果您将继续使用GDI对象,则可以使用一些检漏仪。 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. 设置标签字体时,GDI对象计数增加。 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. 因此,您可以调用该标签的dispose方法,并将字体设置为null或将其设置为空。 This is expected behavior. 这是预期的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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