2013-03-23 4 views
10

Ich verwende eine TableLayoutPanel, die dynamisch mit anderen TablelayoutPanels gefüllt ist.Wie tief säubert Controls.Clear()?

Jetzt frage ich mich, was passiert, wenn ich TableLayoutPanel.Controls.Clear auf dem dynamisch gefüllten TableLayoutPanel aufrufen. Offensichtlich sind alle Unterlayouts entfernt, aber was ist mit ihren Kindern? Sind sie auch richtig entsorgt oder muss ich ein Speicherleck fürchten?

Sollte ich rekursiv die Kinder der Kinder vor dem Aufruf Clear() entfernen?

+1

Wenn kein anderes Objekt einen Verweis auf sie enthält, werden die GC's angezeigt. – Magnus

+0

Richtig, aber ich wundere mich, das Sub-Table- layoutpanel enthält eine Referenz auf seine Kinder und die Kinder eine Referenz auf seine Eltern. Wie kann ich sicher sein, dass der GC die ganze Zeit korrekt entfernt? – Xaser

Antwort

16

Clear enthält die Steuerelemente nicht, was zu einem Speicherleck führt. Von der Verknüpfung:

Aufrufen der Clear-Methode entfernt Steuerelemente nicht aus dem Speicher. Sie müssen die Dispose-Methode explizit aufrufen, um Speicherlecks zu vermeiden.

Da innerhalb einer Schleife Anordnen der Indizierung vermasselt, können Sie entweder die Steuer Sammlung in eine andere Liste kopieren und eine ForEach Schleife auf sie durchführen oder eine rückwärts For Schleife verwenden.

for (int i = myTableLayoutPanelControls.Count - 1; i >= 0; --i) 
    myTableLayoutPanelControls[i].Dispose(); 

Dispose Aufruf wird die Bedienelemente aus dem Speicher entfernen (wenn die GC es nimmt). Dies wird auch den Aufruf der Dispose Methode des untergeordneten Steuerelements behandeln.

Ein Haken ist, wenn Sie ein benutzerdefiniertes Steuerelement haben, das IDisposable implementiert, oder Sie überschreiben die Dispose Methode ohne Aufruf der base Methode. In der Methode Dispose Ihres Objekts müssen Sie sicherstellen, dass Sie sich von Ereignissen außerhalb Ihres Bereichs abgemeldet haben. Wenn Sie dies nicht tun, wird diese Referenz Ihr Objekt am Leben erhalten.

1

Es gibt ein bisschen Verwirrung in Ihrer Frage. Clear() entfernt Referenzen und Objekte werden von Garbage Collector gesammelt.

Aber Sie verwenden auch das Wort dispose. Gelöschte Objekte werden nicht in dem Sinne entsorgt, dass ihre Dispose Methode aufgerufen wird.

Wenn Sie also diese Objekte nicht mehr verwenden und Dispose aufgerufen werden sollen, müssen Sie dies selbst tun.

+0

Okay, dann ist die Frage: SOLLTE ich anrufen, um jedes Objekt, das ich nicht mehr benutze, zu entsorgen, oder ist es okay, wenn ich es einfach entfernen lasse. Ich konnte mir nichts vorstellen, was die Dispose-Methode gerade für das Programm ausmacht. Auch die Frage aus meinem vorherigen Kommentar bleibt bestehen, wenn sich Eltern und Kind gegenseitig ansprechen, wird der GC sie sammeln? – Xaser

+0

Richtig Ich habe getan, was ich getan hätte, bevor ich den obigen Kommentar gepostet habe - Forschung. Wenn ich die MSDN richtig verstanden habe, kann die Dispose-Methode explizit aufgerufen werden und gibt nicht gemanagte Ressourcen frei, was der GC implizit mit der Finalize-Methode macht (falls vorhanden). Wie jedoch in keyboardP gesagt wurde, löscht Clear nicht alle Referenzen, so dass ich Dispose explizit aufrufen muss. – Xaser

+0

@Xaser 'Clear' bereinigt alle internen Referenzen der Steuerelemente. Es wirkt sich nicht auf Referenzen aus, die Sie in Ihrem Code haben.'Finalize 'wird nicht garantiert aufgerufen, und deshalb müssen Sie' Dispose' aufrufen, wenn Sie sicher sein wollen, dass alle nicht verwalteten Ressourcen bereinigt sind. – clearpath