c# - tiradero - ¿Los controladores de eventos detienen la recolección de basura?
servicio de recolección de basura (4)
Si tengo el siguiente código:
MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass = null;
¿Será pClass basura recogida? ¿O seguirá dando vueltas disparando sus eventos cada vez que ocurran? ¿Tendré que hacer lo siguiente para permitir la recolección de basura?
MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass.MyEvent -= MyFunction;
pClass = null;
En el momento en que ya no se hace referencia a una pieza de memoria, se convierte en un candidato para la recolección de basura. Cuando la instancia de su clase queda fuera del alcance, ya no se hace referencia a su programa. Ya no se usa y, por lo tanto, se puede recolectar de forma segura.
Si no está seguro de si algo se recopilará, hágase la siguiente pregunta: ¿todavía existe una referencia al respecto? Los manejadores de eventos son referenciados por la instancia del objeto, y no al revés.
Para la pregunta específica "Will pClass será basura recolectada": la suscripción al evento no tiene ningún efecto en la colección de pClass (como editor).
Para GC en general (en particular, el objetivo): depende de si MyFunction es estático o está basado en instancias.
Un delegado (como una suscripción de evento) a un método de instancia incluye una referencia a la instancia. Entonces, sí, una suscripción a un evento evitará GC. Sin embargo, tan pronto como el objeto que publica el evento (pClass anterior) es elegible para la recopilación, esto deja de ser un problema.
Tenga en cuenta que esto es unidireccional; es decir, si tenemos:
publisher.SomeEvent += target.SomeHandler;
entonces "editor" mantendrá "objetivo" vivo, pero "objetivo" no mantendrá vivo al "editor".
Entonces no: si pClass se va a recopilar de todos modos, no hay necesidad de cancelar la suscripción de los oyentes. Sin embargo, si pClass era de larga vida (más larga que la instancia con MyFunction), entonces pClass podría mantener viva esa instancia, por lo que sería necesario darse de baja si desea que se recopile el objetivo.
Los eventos estáticos, sin embargo, por esta razón, son muy peligrosos cuando se usan con manejadores basados en instancias.
Sí, pClass será basura recolectada. La suscripción al evento no implica que exista ninguna referencia a pClass.
Así que no, no tendrá que desconectar el controlador para que pClass sea basura.
pClass
será basura recolectada. Sin embargo, si el fragmento de código anterior está dentro de otra clase, la instancia de esa clase podría no pClass
si no establece pClass
en null
.