2009-07-28 11 views
1

Ich habe ein Problem mit einem Steuerelement undicht GDI Griffe. Diese ist die abgespeckte Version der Steuerung:VB.NET-Steuerelement GDI-Handle Leck?

 
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 


Wenn ich das Programm laufen, die GDI Objektanzahl ist 38.

Dann öffne ich ein Formular, das nur eine FancyLabel drauf hat und die GDI-Objektanzahl wird auf 42 erhöht.

Ich schließe dann das Formular und die GDI-Anzahl fällt auf 39 und bleibt dort, egal wie viele Instanzen des Formulars ich erstelle und schließe.

Irgendwelche Ideen?

Dank JV

Antwort

1

Also, wenn Sie den Prozess fortsetzen, den Sie 100 Mal in Folge beschrieben, nehme ich an, die GDI-Zahl würde nicht höher als 39 gehen?

Wenn ja, dann müssen Sie damit leben. Die GDI-Objekte, die für Ihr FancyLabel erforderlich sind, werden von .NET nicht direkt verfügbar gemacht. Ich denke, das Beste, was Sie tun können, ist, die Steuerelemente, die die GDI-Objekte enthalten, bei jeder Gelegenheit zu entfernen. Aber in deinem Fall klingt es so, als wäre dein Leck nicht so schlimm und wahrscheinlich nicht die Mühe wert.

Es sind die Lecks, die weiterhin GDI-Objekte mit wiederholtem Gebrauch aufbauen und konsumieren, auf die Sie wirklich achten müssen. Nur für Tritte sind die GDI-Objekttypen aufgeführt here. Diese Referenz hat keine direkte Korrelation zu Windows Forms-Steuerelementen, aber Sie können sich vorstellen, was einige Steuerelemente möglicherweise verwenden (und ich bin sicher, dass das an anderer Stelle dokumentiert ist).

Glücklicherweise ist Microsoft endlich von GDI-Objekten mit WPF weggegangen. Eine reine WPF-Anwendung verwendet nur 2 GDI-Objekte für das Fenster selbst (der Rest der Benutzeroberfläche ist GDI-frei). Wenn Sie also gerade am Anfang des Projekts sind, an dem Sie gerade arbeiten, ist es jetzt vielleicht an der Zeit, WPF in Betracht zu ziehen. ;)

+0

Ich stimme zu: Wenn das Hinzufügen von 10 FancyLabels dazu führt, dass die Anzahl nicht höher als 39 ist, leckt deine Kontrolle nicht wirklich, etwas anderes passiert. – OwenP

1

Nun, die GDI Zahl zu erhöhen, um Windows Forms zurückzuführen sein könnte. Windows Forms verwendet indirekt GDI, wenn das System einige Steuerelemente rendert. Sie können .NET Memory Profiler verwenden, um herauszufinden, wo sich das Leck befindet und wie es gelöst werden kann.

EDIT: GDI-Objekte werden nicht automatisch vom Garbage Collector abgeholt. Sie sollten die Dispose-Methode überschreiben und sicherstellen, dass alle GDI-Objekte ordnungsgemäß entsorgt werden.

+0

Das Formular enthält keine weiteren Steuerelemente. Wenn ich das FancyLabel mit nur der normalen System.Windows.Forms.Label ersetzen, funktioniert alles wie erwartet, dh. Die endgültige GDI-Zählung ist zurück auf 37, nachdem ich das Formular geschlossen habe. –

+0

"GDI-Objekte werden nicht automatisch vom Garbage Collector übernommen. Sie sollten die Dispose-Methode überschreiben und sicherstellen, dass alle GDI-Objekte ordnungsgemäß entsorgt werden." Ja, ich stimme zu, aber wie Sie sehen können, ich ein GDI-Objekt nirgendwo erstellen, ich ändern nur einen Aufzählungswert für vorhandene Grafikobjekt. Das ist der Teil, der mich verwirrt ... –

0

Wenn Sie weiterhin mit GDI-Objekten arbeiten, können Sie einige Leck-Detektoren verwenden. Wenn Sie ein solches Programm verwenden, sehen Sie einen vollständigen Stapel, der anzeigt, wo jedes Objekt erstellt wurde.

-1

GDI-Objekte zählen erhöhen, wenn Sie Label-Schriftart festlegen. Sie können also die dispose-Methode dieser Beschriftung aufrufen und die Schriftart als null oder nichts festlegen, wenn Sie sie loswerden möchten. Dies ist das erwartete Verhalten.