2013-03-23 18 views
10

Sto utilizzando uno TableLayoutPanel che viene riempito dinamicamente con altri TablelayoutPanels.Quanto profondo pulisce Controls.Clear()?

Ora mi chiedo cosa succede quando chiamo TableLayoutPanel.Controls.Clear sul dinamico riempito TableLayoutPanel. Ovviamente, tutti i sottosquadri vengono rimossi, ma per quanto riguarda i loro figli? Sono disposti correttamente o devo temere una perdita di memoria?

Devo rimuovere in modo ricorsivo i figli dei bambini prima di chiamare Clear()?

+1

Se nessun altro oggetto è in possesso di un riferimento ad essi, i GC sono disposti. – Magnus

+0

Giusto, ma mi chiedo, il pannello Sub-Tablelayout contiene un riferimento sui suoi figli e i bambini un riferimento sul suo genitore. Come posso essere sicuro che il GC li rimuove sempre correttamente – Xaser

risposta

16

Clear non dispone i controlli, causando una perdita di memoria. Dal collegamento:

La chiamata del metodo Clear non rimuove le maniglie di controllo dalla memoria. È necessario chiamare esplicitamente il metodo Dispose per evitare perdite di memoria.

Poiché lo smaltimento all'interno di un ciclo scombina l'indicizzazione, è possibile copiare la raccolta di controllo ad un altro elenco ed eseguire un ciclo ForEach su di loro o utilizzare un all'indietro For ciclo.

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

Calling Dispose rimuoverà i controlli dalla memoria (quando il GC raccoglie). Ciò gestirà anche la chiamata del metodo Dispose del controllo figlio.

Un problema è se si dispone di un controllo personalizzato che implementa IDisposable o si sta sovrascrivendo il metodo Dispose senza chiamare il metodo base. Nel metodo Dispose del tuo oggetto devi assicurarti di aver annullato l'iscrizione a eventi al di fuori del tuo ambito. Se non lo fai, quel riferimento manterrà vivo il tuo oggetto.

1

C'è un po 'di confusione nella tua domanda. Clear() rimuoverà i riferimenti e gli oggetti verranno raccolti dal garbage collector.

Tuttavia, si sta utilizzando anche la parola dispose. Gli oggetti eliminati saranno non da smaltire nel senso che verrà chiamato il loro metodo Dispose.

Pertanto, se non si utilizzano più tali oggetti e si desidera che venga chiamato Dispose, è necessario farlo da soli.

+0

Ok, quindi la domanda è DOVREBBE che chiamo di disporre su ogni oggetto che non sto usando più o è okayish se ho appena lasciato il gc rimuoverlo. Non riesco a pensare a qualcosa che il metodo Dispose fa è fondamentale per il programma proprio ora. Anche la domanda del mio precedente commento persiste, in quanto genitori e figli si richiamano l'un l'altro, il GC li raccoglierà? – Xaser

+0

Giusto ho fatto quello che avrei dovuto fare prima di postare il commento sopra: la ricerca. Se ottengo il diritto MSDN, il metodo Dispose può essere chiamato esplicitamente e libera risorse non gestite, ciò che il GC utilizza implicitamente con il metodo finalize (se disponibile). Tuttavia, come detto tastieraP, Clear non cancella tutti i riferimenti quindi devo chiamare Dispose in modo esplicito. – Xaser

+0

@Xaser 'Clear' cancella tutti i riferimenti interni ai controlli. Non influenzerà i riferimenti che hai nel tuo codice.'Finalize' non è garantito per essere chiamato ed è per questo che è necessario chiamare' Dispose' se si vuole essere certi che tutte le risorse non gestite vengano ripulite. – clearpath

Problemi correlati