2010-04-10 4 views
8

Nach my question here, wenn ich ein Bild in einem Bildfeld ersetzen, sollte ich das Originalbild zuerst entsorgen?Wenn ich ein Bild in einem PictureBox-Steuerelement ersetze, sollte ich das Originalbild zuerst entsorgen? .Net Winforms

Oder was über diese Situation:

Dim bm As New Bitmap(32,32) 
bm = New Bitmap(32,32) 
bm = New Bitmap(32,32) 
bm = New Bitmap(32,32) 

Does bm braucht nur am Ende entsorgt werden, oder sollte es vor jeder Neuschöpfung entsorgt werden?


Vielen Dank für die Antworten. Ein großes Versehen meinerseits. Ich wusste, dass eine Kontrolle sich darum kümmerte, ihre Kinder zu entsorgen, aber es war mir nicht in den Sinn gekommen, dass ich ein altes Bild entsorgen sollte, wenn ich es ersetzen würde.

Antwort

5

Ja, Sie sollten das alte Objekt entsorgen, bevor Sie ein neues Bild über der gleichen Variablen erstellen. Wenn Sie ein neues Bild mit derselben Variablen erstellen, entfernen Sie einen Verweis darauf. Wenn es keine Referenzen auf das alte Objekt gibt, bedeutet dies, dass es vom GC (Garbage Collector) abgeholt werden sollte. Obwohl dies "theoretisch" dazu führen sollte, dass der Speicher freigegeben wird, vorausgesetzt, dass der Finalizer dafür sorgt, dass nicht verwaltete Ressourcen berücksichtigt werden, ist dies eine große Annahme (Sie können nicht wirklich davon ausgehen, dass der Finalizer aufgerufen wird). und es verursacht mehr Arbeit für das System. Nicht standardmäßige Finalizer verursachen zusätzliche Arbeit für den GC in Bezug auf die Garbage-Collection-Level-Promotion, was dazu führt, dass die Deallokierung des Speichers länger dauert und die Anzahl der Male, die der GC dazu ausgeführt werden muss.

Dies wird davon ausgegangen, dass alle geschrieben wird, um sicherzustellen, dass der Finalizer es behandelt. Jedes Mal, wenn ein Objekt eine Dispose-Methode hat (alles, was IDisposable implementiert, was BitMap tut), sollte es aufgerufen werden, bevor die Referenz auf das Objekt entfernt wird (außerhalb des Gültigkeitsbereichs, Entfernung der Referenz auf das Objekt usw.). Hier

ist ein Artikel darüber, wie der Garbage Collector arbeitet in .net

http://www.devx.com/dotnet/Article/33167

Hier ist, wie MS sagt der dispose/Finalizerthread umgesetzt werden sollten:

http://msdn.microsoft.com/en-us/library/b1yfkh5e.aspx

2

Ja, Sie sollte. Es implementiert IDisposable.
Als allgemeine Faustregel gilt: Entsorgen Sie alle Objekte, die IDisposable implementieren. Überlassen Sie es nicht GC.

2

Muss bm nur am Ende entsorgt werden, oder sollte es vor jeder Neuerstellung entsorgt werden?

Es sollte vor jeder "Erholung" entsorgt werden. Verwechseln Sie ein Objekt nicht mit einer Objektreferenz. "new Bitmap" erstellt ein neues Objekt. "bm" ist eine Referenz, die zufällig auf dieses Objekt zeigt. Sie sind nicht gleich. Sie "erstellen" hier kein Objekt neu - Sie erstellen ein neues Objekt und löschen dann alle Referenzen auf das vorherige Objekt, was bedeutet, dass ich irgendwann in der (nahen) Zukunft Müll gesammelt werde.

+0

Vielen Dank für das Sie sich für mich zu löschen. Ich kenne alle Konzepte in Ihrer Antwort, aber an manchen Tagen habe ich ein Gehirnfrost! Schon mal vergessen, wie man ein kurzes Wort buchstabiert? So fühlt es sich an. – Jules

2

Wenn Sie das Bild ändern, das mit einem PictureBox verknüpft ist, sollte man Dispose auf dem Bild aufrufen, das dort war, wenn und nur wenn nichts anderes jemals das Bild verwenden wird. Um das zu wissen, müsste man wissen, woher das alte Bild kam. In einigen Fällen wurde das Bild nur erstellt, um dem PictureBox zugewiesen zu werden. In anderen Fällen könnte das Bild eines sein, das geteilt und/oder wiederverwendet werden soll.Wenn Bild ausschließlich zum Zweck der Zuordnung zum PictureBox erstellt wurde, soll es Dispose d sein, wenn die PictureBox angeordnet ist oder ein anderes Bild gegeben. Wenn das Bild geteilt oder wiederverwendet werden soll, dürfen diese Bedingungen nicht dazu führen, dass es entsorgt wird.

Der richtige Weg, solche Fragen im Allgemeinen würde für die Klassen zu lösen, die IDisposable Eigenschaften (wie die PictureBox, mit Image) eher eine explizite SetImage Methode zu verwenden, als eine veränderbare Image Eigenschaft und für die SetImage Verfahren ein schließen Parameter, der angibt, ob die PictureBox Verantwortung für die Entsorgung übernehmen soll. Der Aufruf SetImage oder Dispose auf der PictureBox sollte Dispose auf dem gehaltenen Bild aufrufen, wenn und nur wenn der vorherige SetImage nennen es die Verantwortung gab. Leider funktioniert PictureBox nicht so, aber ich würde für zukünftige Klassen Sie die IDisposable Objekte halten schreiben mit, dass als Muster sehr empfehlen.

+0

Das ist die einzige Antwort, um den ersten Teil der Frage sprechen, ob ein 'PictureBox' Bild zu entsorgen, bevor zuweisen. –

+1

@UweKeim: Ich dachte, es war ein wichtiges Thema, das keiner der anderen Antworten auf berührt. Froh, dass Sie meine Antwort hilfreich fanden. Ich vermute, dass das Framework geschrieben wurde, bevor die Leute wirklich herausgefunden haben, wie IDisposable funktionieren würde, und diese alten Klassen sind in Stein gemeißelt, aber es gibt keinen Grund, dass neuere Klassen die alten Fehler wiederholen sollten. – supercat

Verwandte Themen