2009-07-28 39 views
1

GDIハンドルが漏れているコントロールに問題があります。 これは、コントロールのカットダウン版です:私はプログラムを実行すると、GDIオブジェクト数が38

その後、私はそれで一つだけFancyLabelを持つフォームを開くですVB.NETコントロールの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オブジェクトの数は42に増えます。

フォームを閉じると、GDIのカウントは39に下がり、作成して閉じるフォーム のインスタンス数に関係なく、そのまま残ります。

すべてのアイデア?

おかげJV

答えて

1

あなたが連続して100回記述したプロセスを続けると、GDIカウントは39を超えないと仮定します。

もしそうなら、これはあなたが住んでいなければならないものかもしれません。 FancyLabelに必要なGDIオブジェクトは、.NETが直接公開するものではありません。私はあなたができるベストは、すべての機会にGDIオブジェクトを含むコントロールを処分することだと思います。しかし、あなたのケースでは、あなたのリークがそれほど悪くなく、おそらく問題の価値がないように思えます。

繰り返して使用するGDIオブジェクトを構築し消費することは、本当に目にする必要があるリークです。ちょうどキックのために、GDIオブジェクトタイプはhereと記載されています。このリファレンスはWindowsフォームコントロールへの直接的な関連付けを持っていませんが、いくつかのコントロールが何を使用しているのか想像してみることができます(そして、それは別のところで文書化されています)。

幸いにも、Microsoftは最終的にWPFでGDIオブジェクトから離れました。純粋なWPFアプリケーションは、ウィンドウ自体に2つのGDIオブジェクトしか使用しません(残りのUIはGDIフリーです)。ですから、あなたが作業しているプロジェクトの初めの段階にいるのであれば、おそらくWPFを検討するのがいいでしょう。 ;)

+0

10個のFancyLabelsを追加すると、カウントが39を超えないようになると、コントロールが実際に漏れているわけではなく、何か他のことが起こっています。 – OwenP

1

はまあGDIカウントは、Windowsフォームのために増加することができます。 Windowsフォームは、システムがいくつかのコントロールをレンダリングしているときに間接的にGDIを使用します。 .NET Memory Profilerを使用して、リークがどこにあるかを調べ、解決方法を判断できます。

EDIT: GDIオブジェクトが自動的にガベージコレクタによってピックアップされていません。 Disposeメソッドをオーバーライドして、すべてのGDIオブジェクトが適切に処理されていることを確認する必要があります。

+0

フォームに他のコントロールはありません。 通常のSystem.Windows.Forms.LabelだけでFancyLabelを置き換えると、すべて正常に動作します。最終的なGDIカウントは、フォームを閉じると37に戻ります。 –

+0

"ガベージコレクタによってGDIオブジェクトが自動的に選択されないため、Disposeメソッドをオーバーライドして、すべてのGDIオブジェクトが適切に処分されるようにする必要があります。" 私は同意しますが、わかりましたが、私はGDIオブジェクトをどこにも作成していません。既存のGraphicsオブジェクトの列挙値を変更しています。 それは私を混乱させる部分です... –

0

GDIオブジェクトを使用して作業を続ける場合は、いくつかのリークディテクタを使用できます。このようなプログラムを使用すると、各オブジェクトがどこに作成されたかを示す完全スタックが表示されます。

-1

ラベルフォントを設定すると、GDIオブジェクト数が増加します。したがって、そのラベルのdisposeメソッドを呼び出すことができ、それを取り除きたい場合は、フォントをnullまたは何も設定しないでください。これは予想される動作です。

関連する問題