Voy a crear una GUI que creará dinámicamente conjuntos de controles con eventos asignados. Tendré que agregar y quitar esos controles en tiempo de ejecución. Se parece a esto:precauciones para evitar fugas de memoria debido a controladores de eventos agregados
FlowLayoutPanel.Controls.Clear();
<< add new controls, assigning Click events with += >>
He oído que la asignación de controladores de eventos con + = puede causar pérdidas de memoria (más especificamente, no se liberará la memoria hasta que la aplicación ha salido). Quiero evitar esto. Sé que puedo escribir algunas funciones como aquí How to remove all event handlers from a control para encontrar todos los controladores de eventos y eliminarlos, pero se ve muy complejo.
¿Hay alguna otra manera? ¿Llamar a Dispose ayuda a eliminar esos controladores de eventos? ¿Puedes destruir objetos para forzar que su memoria sea liberada como en C/C++?
Gracias!
PD: El problema es que no sé qué evento desacoplar. Crearé muchas etiquetas y les agregaré diferentes tipos de eventos onclick. Cuando es hora de limpiar el panel de diseño de flujo, no hay forma de saber qué controlador de eventos se adjuntó a qué etiqueta.
Este es el código de ejemplo (_flowLP es un FlowLayoutPanel) - esta función Refresh() se ejecuta varias veces antes de que la aplicación finalice.
private void Refresh()
{
Label l;
Random rnd = new Random();
// What code should i add here to prevent memory leaks
_flowLP.Controls.Clear();
l = new Label();
l.Text = "1";
if (rnd.Next(3) == 0) l.Click += Method1;
if (rnd.Next(3) == 0) l.Click += Method2;
if (rnd.Next(3) == 0) l.Click += Method3;
_flowLP.Controls.Add(l);
l = new Label();
l.Text = "2";
if (rnd.Next(3) == 0) l.Click += Method1;
if (rnd.Next(3) == 0) l.Click += Method2;
if (rnd.Next(3) == 0) l.Click += Method3;
_flowLP.Controls.Add(l);
l = new Label();
l.Text = "3";
if (rnd.Next(3) == 0) l.Click += Method1;
if (rnd.Next(3) == 0) l.Click += Method2;
if (rnd.Next(3) == 0) l.Click += Method3;
_flowLP.Controls.Add(l);
l = new Label();
l.Text = "4";
if (rnd.Next(3) == 0) l.Click += Method1;
if (rnd.Next(3) == 0) l.Click += Method2;
if (rnd.Next(3) == 0) l.Click += Method3;
_flowLP.Controls.Add(l);
l = new Label();
l.Text = "5";
if (rnd.Next(3) == 0) l.Click += Method1;
if (rnd.Next(3) == 0) l.Click += Method2;
if (rnd.Next(3) == 0) l.Click += Method3;
_flowLP.Controls.Add(l);
l = new Label();
l.Text = "6";
if (rnd.Next(3) == 0) l.Click += Method1;
if (rnd.Next(3) == 0) l.Click += Method2;
if (rnd.Next(3) == 0) l.Click += Method3;
_flowLP.Controls.Add(l);
}
En cuanto a su edición: si los métodos añadidos a la lista de invocación de un evento no se pueden determinar con certeza, puede mantener los delegados que se han agregado a los manejadores de eventos en una colección en algún lugar y usar eso para eliminar los delegados cuando proviene. O bien, si sabe que está borrando por completo las listas de invocación de los eventos, simplemente borre todo. – phoog