2010-08-26 12 views
5

Tengo un formulario con un panel en el que cargo dinámicamente varios controles de usuario. Manejo eventos para cada uno de estos controles.Control de usuario cargado dinámicamente con controladores de eventos: cancelar el registro

UserControl userControl1 = LoadControl("control.ascx") as UserControl; 
userControl1.Event += new ControlEventHandler(userControl_Event); 
this.Panel.Controls.Add(userControl1); 

UserControl userControl2 = LoadControl("control.ascx") as UserControl; 
userControl2.Event += new ControlEventHandler(userControl_Event); 
this.Panel.Controls.Add(userControl2); 

... 

Ahora, cuando me deshago de los controles en el panel, simplemente hago un

this.Panel.Controls.Clear(); 

hace la función Clear() cuidar de deshacerse de los eventos o debería estar haciendo

foreach(Control control in this.Panel.Controls) 
{ 
    UserControl userControl = control as UserControl; 
    if(userControl != null) 
    { 
     userControl -= userControl_Event; 
    } 
} 

antes de borrar() el contenido del panel?

Básicamente, estoy buscando una forma de cargar controles de usuario dinámicamente y manejar sus eventos sin crear una fuga cuando me deshago de ellos.

Gracias!

EDIT: Debido a que mis controles se crean en el caso Page_Init de la página (cada vez, a medida que se cargan dinámicamente), ¿es correcto decir que su esperanza de vida no puede ser más larga que la vida útil de la página? Según tengo entendido, el control no existe después de una publicación posterior. Se crea una nueva cada vez. Por lo tanto, no debería tener que anular el registro del evento porque el objeto ni siquiera existe en la carga de la página siguiente. ¿Es eso correcto?

Respuesta

5

La página contendrá referencias a los controles dinámicamente instanciados incluso después de la recolección se ha borrado, lo que evitará que los controles sean recogidos hasta la página se recolecta a sí misma.

En esta situación particular, esto funcionará bien porque la vida de la página es muy corta.

Sin embargo, si esto fuera una aplicación de formularios de windows, entonces la memoria se filtraría efectivamente hasta que se liberara el formulario.

En general, es una buena idea darse de baja de sus eventos cuando libera los objetos a los que van los eventos, ya que esta es la fuente de la gran mayoría de las pérdidas de memoria .net.

0

el recolector de basura debe ser capaz de recogerlas sin que tenga que anular el registro

2

Esta página en MSDN responde a su pregunta:

Control..::.ControlCollection..::.Clear Method

citándolo:

Importante

Al llamar al método Clear no maneja no control de quitar de la memoria. Debe llamar explícitamente al método Dispose para evitar pérdidas de memoria.

0

Es correcto decir que la vida útil de los controles de usuario que se cargan dinámicamente no puede durar más que la página a la que pertenece.Pero no podemos decir que esto sea cierto en el caso de eliminar un control web de la colección de control de página y asignarlo a, por ejemplo, una variable de sesión que puede causar que el control web tenga una vida útil más larga que la página. Entonces, no siempre es correcto

Es importante cancelar su suscripción a un evento si se suscribe al evento de un objeto de larga vida (como objeto singleton u objetos almacenados con aplicación, sesión y caché en asp.net) con un método de vida corta objeto (como página, control de usuario o control web, etc.).

Por ejemplo

UserControl uc = LoadControl("control.ascx") as UserControl; 
SomeObject so=Session["SomeObject"] as SomeObject; 
If(so!=null) 
{ 
    so.SomeEvent += new SomeEventHandler(uc.SomeMethod); 
} 

Aquí hay que estar inscrita en el caso de no causar una pérdida de memoria.

Finalmente, no tiene que preocuparse por los eventos registrados en su caso. Ellos serán recogidos por el recolector de basura.

0

El hecho de que llame al controls.Clear en el panel es evidencia suficiente de que también debe anular el registro de los eventos.

Para hacer eso, podría crear su propia colección de control, con el código de anulación de registro en el método Clear anulado, luego de crear su propio panel que use su nueva colección, devuelta de un valor de propiedad Controls anulado.

Cuestiones relacionadas