繁体   English   中英

VB.NET控件GDI处理泄漏?

[英]VB.NET control GDI handle leak?

我有一个控件泄漏GDI句柄的问题。 这是控件的简化版本:

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


当我运行程序时,GDI对象计数为38。

然后,我打开一个只有一个FancyLabel的表单,GDI对象计数增加到42。

然后,我关闭该表单,无论创建和关闭多少个表单实例,GDI计数都会降至39,并保持在那里。

有任何想法吗?

谢谢合资

好吧,由于Windows窗体,GDI计数可能会增加。 系统呈现某些控件时,Windows窗体间接使用GDI。 您可以使用.NET Memory Profiler找出泄漏所在,并确定如何解决泄漏。

编辑:垃圾收集器不会自动拾取GDI对象。 您应该重写Dispose方法,并确保正确处置所有GDI对象。

因此,如果您连续进行100次描述的过程,那么我认为GDI计数不会超过39?

如果是这样,这可能是您必须忍受的。 FancyLabel必需的GDI对象不是.NET直接公开的对象。 我认为您能做的最好的就是在每一个机会处都放置包含GDI对象的控件。 但是,就您而言,这听起来好像泄漏并不严重,可能不值得您为此烦恼。

您确实需要注意的是,泄漏会继续累积并消耗重复使用的GDI对象。 仅用于踢球, 此处列出了GDI对象类型。 此参考与Windows Forms控件没有直接关系,但是您可以想象一下某些控件可能正在使用什么(并且我确定在其他地方都有说明)。

幸运的是,Microsoft终于使用WPF摆脱了GDI对象。 一个纯WPF应用程序将仅对窗口使用2个GDI对象(UI的其余部分不包含GDI)。 因此,如果您只是处于项目的开始阶段,那么现在也许是考虑使用WPF的好时机。 ;)

如果您将继续使用GDI对象,则可以使用一些检漏仪。 如果使用此类程序,则会看到完整的堆栈,其中显示了每个对象的创建位置。

设置标签字体时,GDI对象计数增加。 因此,您可以调用该标签的dispose方法,并将字体设置为null或将其设置为空。 这是预期的行为。

暂无
暂无

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

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