Todo el mundo está olvidando un muy detalle importante: tienes que Dispose() el control o que se escapará para siempre:
for (int ix = this.Controls.Count - 1; ix >= 0; ix--) {
if (this.Controls[ix] is PictureBox) this.Controls[ix].Dispose();
}
Voy a poner un poco más de énfasis en el forever cláusula, hay mucho clamor al respecto en los comentarios, la clase Control no se comporta como cualquier otra clase .NET. Un control se mantiene vivo por su propiedad Handle
. Que almacena el manejo nativo de Windows. Mientras exista la ventana nativa, el objeto Control no se puede destruir.
Esto requiere que el objeto se mantenga con vida artificialmente cuando utiliza Borrar() o Eliminar() y elimina el control de su elemento primario. Winforms usa la llamada "ventana de estacionamiento" como el anfitrión de tales controles. Es una ventana nativa normal como cualquier otra, simplemente no es visible. Su trabajo es ser el padre de dichos controles huérfanos.
La ventana de estacionamiento permite muchos trucos aseados que normalmente son muy difíciles de hacer en Windows. Puede, por ejemplo, activar y desactivar la propiedad ShowInTaskbar en tiempo de ejecución. Una propiedad de una ventana que normalmente solo se puede especificar al crear la ventana (estilo WS_EX_APPWINDOW, especificado en la llamada a CreateWindowEx()). Las formas de Win pueden hacerlo incluso después de haber creado la ventana moviendo los controles del formulario a la ventana de estacionamiento, destruyendo la ventana, volviéndola a crear y moviendo los controles hacia atrás. Ordenado.
Pero con el hang-up no tan lindo que es el tema de esta respuesta, si elimina el control y no llame a su método Dispose(), entonces continuará sobreviviendo en la ventana de estacionamiento. Siempre. Una verdadera filtración. Nada que el recolector de basura pueda hacer al respecto, ve una referencia válida al objeto. Una violación bastante grave del contrato IDisposable, llamando a Dispose() es opcional, pero es no para la clase Control.
Afortunadamente, este error es bastante fácil de diagnosticar, no requiere ninguna herramienta especial, puede ver la fuga en la pestaña Procesos del Administrador de tareas. Agregue la columna "Objetos del USUARIO".
+ 1..gracias por eso, lo olvidé por completo. de hecho controla el método de eliminación de llamadas parent.Controls.Remove (this) –
No se filtrará para siempre ... solo se filtrará hasta que aparezca el recolector de basura ... y con suerte el destructor de PictureBox incluye una llamada a Dispose. – Nick
@Stan R - ¿Lo hace? Genial ... ¡No lo sabía! – Nick