2009-12-28 9 views
8

hay múltiples hilos (a, b, c etc.) sobre el hecho de que Claro() artículos ING en los contenedores de componentes .NET no Desechar ellos (llamando al botar (cierto).Los controles claros no los eliminan, ¿cuál es el riesgo?

Con mayor frecuencia, en mi humilde opinión, los componentes Claro-ed no se utilizan más en la aplicación, por lo que necesita de forma explícita desecharse después de su remoción de los contenedores primarios.

Tal vez es una buena idea que el método de recogida Clear tenía un bool parámetro dispose que cuando está en verdad también dispone los elementos de colección antes de su eliminación de la lista?

+0

Si hay una llamada a disponer en el finalizador, obtendrán dispuestos. Si no lo hay, entonces probablemente (si el programador siguió las prácticas aceptadas) no hay nada que no se pueda administrar y es seguro que solo la basura los recolecte. –

+0

@Aviad: el problema de que el GC nunca llamará al método Dispose, por lo que debe hacerlo usted mismo, antes de llamar a Clear on collection. – serhio

+0

Lo que quiero decir es que si el programador del control no puso una llamada Dispose en su finalizador (que se llama cuando el objeto es basura), entonces probablemente no haya nada que desechar. –

Respuesta

15

Pedir modificaciones como esta no tiene sentido, el equipo de Windows Forms se ha disuelto hace bastante tiempo. Está en modo de mantenimiento, solo se consideran los problemas de seguridad y las incompatibilidades del sistema operativo.

Es otra manera lo suficientemente simple para crear su propio método para hacer esto:

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); 
     } 
    } 
    } 

Ahora se puede escribir:

panel1.Controls.Clear(true); 
+1

IIRC, cuando 'Desecha' un' Control', elimina automáticamente el control del 'ControlCollection' correspondiente, por lo que en realidad no necesita el 'RemoveAt' (y podría terminar con un' IndexOutOfRangeException'). – Aaronaught

+0

sí ... al menos para .NET 2 esto no funcionará. Pero la pregunta es un poco diferente. ¿Existe un "riesgo" de llamar a "Borrar" sin desechar? – serhio

+2

Por supuesto, perderá los controles. ¿No era obvio de los otros hilos? –

0

Respondiendo a la "¿cuál es el riesgo" cuestión, el riesgo (o un riesgo) se está quedando sin controladores de ventana, aunque puede llevar un tiempo.

Tengo un "diseñador de ventanas" que genera una ventana desde un script. Cada vez que cambio la secuencia de comandos, la ventana se reconstruye (los controles se borran y se leen). Con una ventana particularmente compleja y usando Controls.Clear() cada vez, después de muchas docenas de actualizaciones, eventualmente obtendré una excepción de "no más controladores de ventanas" y no podré crear más controles.

Es bastante fácil de reemplazar la llamada Controls.Clear() con algo como:

Controls.Cast<Control>().ForEach(c => c.Dispose()); 
Cuestiones relacionadas