Tenemos una aplicación de Windows Forms que contiene miles de formularios.Usando una declaración en el formulario de diálogo para asegurar la recolección de basura
Muchos de estos se muestran temporalmente como cuadros de diálogo mediante el método ShowDialog().
Esta aplicación existe desde hace años y descubrimos que muchos de los formularios no reciben basura recolectada de manera oportuna debido a varias filtraciones de recursos en la forma o los controles que utiliza.
Específicamente, hemos encontrado ejemplos de recursos de GDI + que no se eliminan correctamente, aunque puede haber otros tipos de pérdidas de recursos que aún no se han caracterizado.
Aunque la forma correcta de resolver esto es, obviamente, pasar por cada forma y cada control y eliminar todos los problemas de recursos. Esto tomará un tiempo para lograrlo.
Como una alternativa a corto plazo, hemos encontrado que llamar explícitamente a Dispose() en el formulario parece iniciar el proceso de recolección de basura y la forma y sus recursos se desasignan inmediatamente.
Mi pregunta es si sería una solución razonable para envolver el bloque ShowDialog() de cada formulario en una declaración using para que se llame a Dispose() después de que se haya mostrado el formulario, y también sería una buena práctica instituir ¿en general?
Por ejemplo, cambie el código existente de esto:
public void ShowMyForm()
{
MyForm myForm = new MyForm();
myForm.ShowDialog();
}
A esto:
public void ShowMyForm()
{
using (MyForm myForm = new MyForm())
{
myForm.ShowDialog();
}
}
En nuestras pruebas, a disponer de MiFormulario() método nunca se llamó para el primer ejemplo, pero se llama inmediatamente para el segundo ejemplo.
¿Esto parece un enfoque razonable como una solución a corto plazo mientras pasamos el tiempo rastreando cada uno de los problemas de recursos específicos?
¿Existen otros enfoques que podríamos considerar para una solución a corto plazo y/o metodologías para identificar y resolver este tipo de problemas de recursos?
Sí, esta es la mejor práctica para los diálogos de uso y descarte. Además, Dispose solo se invocará si lo llamas explícitamente (como mediante 'using'), por lo que si tienes recursos no administrados, es posible que necesites implementar un finalizador o usar clases de contenedor como varios derivados de SafeHandle para asegurarte de que los recursos estén limpiado incluso si no se llama Dispose. –
Tenga en cuenta que hay una gran diferencia entre Dispose() y GC. Eliminar es lo correcto que hay que hacer aquí, y liberará los recursos no administrados, pero no es GC. –
Nota: el uso de 'Controls.Clear();' puede causar una pérdida de memoria. Vea el comentario de Hans aquí http://stackoverflow.com/a/7706549/939213. – ispiro