2009-12-28 10 views
8

Non ci sono più thread (a, b, c ecc) circa il fatto che Cancella() ing oggetti nei contenitori dei componenti .NET non Smaltire loro (chiamando Dispose (vero).I controlli chiari non li eliminano: qual è il rischio?

più delle volte, secondo me, i componenti Clear-ED sono non più utilizzata nell'applicazione, quindi ha bisogno esplicitamente essere smaltiti dopo di loro Cancellazione dai contenitori padre.

Forse è una buona idea che il metodo di raccolta Clear aveva un bool parametro dispose che, quando è vero, dispone anche gli elementi della raccolta prima della sua rimozione dall'elenco?

+0

Se c'è una chiamata di disporre nel finalizzatore, che riceveranno disposti. Se non c'è, allora c'è probabilmente (se il programmatore ha seguito le pratiche accettate) nulla di non gestito da smaltire ed è sicuro solo raccoglierli. –

+0

@Aviad: il problema che il metodo Dispose non verrà mai chiamato dal GC, quindi è necessario farlo da solo, prima di chiamare Clear on collection. – serhio

+0

Quello che voglio dire è che se il programmatore del controllo non ha inserito una chiamata Dispose nel suo finalizzatore (che viene chiamato quando l'oggetto viene sottoposto a garbage collection), allora probabilmente non c'è nulla da smaltire. –

risposta

15

Chiedendo modifiche come questo è inutile, il Windows Form squadra è stato sciolto un po 'di tempo fa. È in modalità di manutenzione, vengono considerati solo problemi di sicurezza e incompatibilità del sistema operativo.

E 'comunque abbastanza semplice per creare il proprio metodo per fare questo:

public static class ExtensionMethods { 
    public static void Clear(this Control.ControlCollection controls, bool dispose) { 
     for (int ix = controls.Count - 1; ix >= 0; --ix) { 
     if (dispose) controls[ix].Dispose(); 
     else controls.RemoveAt(ix); 
     } 
    } 
    } 

Ora si può scrivere:

panel1.Controls.Clear(true); 
+1

IIRC, quando si 'Dispose' un' Control', rimuove automaticamente il controllo dal corrispondente 'ControlCollection', così in realtà non è necessario il 'RemoveAt' (e potrebbe finire con un' IndexOutOfRangeException'). – Aaronaught

+0

sì ... almeno per .NET 2 questo non funzionerà. Ma la domanda è un po 'diversa. C'è un "rischio" nel chiamare "Clear" senza Dispose? – serhio

+2

Ovviamente, perderai i controlli. Non era così ovvio dagli altri thread? –

0

Rispondere alla "qual è il rischio" questione, il rischio (o un rischio) sta finendo le maniglie delle finestre, anche se può richiedere del tempo.

Ho un "window designer" che genera una finestra da uno script. Ogni volta che cambio lo script, la finestra viene ricostruita (i controlli vengono cancellati e letti). Con una finestra particolarmente complessa, e usando Controls.Clear() ogni volta, dopo molte dozzine di aggiornamenti, alla fine otterrò un'eccezione "niente più handle di finestre" e non sarò in grado di creare altri controlli.

Abbastanza facile da sostituire la chiamata Controls.Clear() con qualcosa di simile:

Controls.Cast<Control>().ForEach(c => c.Dispose()); 
Problemi correlati