¿Los controladores de eventos impiden que ocurra la recolección de basura?


Si tengo el siguiente código:

MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass = null;

¿Será pClass basura recolectada? ¿O se quedará por ahí todavía 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;
Author: Cœur, 2008-11-18

4 answers

Para la pregunta específica "Will pClass be garbage collected": la suscripción de eventos no tiene ningún efecto sobre la colección de pClass (como el editor).

Para GC en general (en particular, el destino): depende de si myFunction es estática o basada en instancias.

Un delegado (como una suscripción de eventos) a un método de instancia incluye una referencia a la instancia. Así que sí, una suscripción de evento evitará GC. Sin embargo, tan pronto como el objeto que publica el evento (pClass anterior) es elegible para la recolección, esto deja de ser un problema.

Tenga en cuenta que esto es unidireccional; es decir, si tenemos:

publisher.SomeEvent += target.SomeHandler;

Entonces "publisher" mantendrá "target" vivo, pero "target" no mantendrá "publisher" vivo.

Así que 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 duración (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 controladores basados en instancias.

 182
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-18 10:56:09

Sí, pClass será basura recolectada. La suscripción al evento no implica que exista ninguna referencia a pClass.

Así que no, no tendrá que separar el controlador para que pClass sea recolectado como basura.

 6
Author: Tor Haugen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-18 10:06:30

En el momento en que un pedazo de memoria ya no se hace referencia se convierte en un candidato para la recolección de basura. Cuando la instancia de su clase se sale del ámbito, su programa ya no hace referencia a ella. Ya no se utiliza y, por lo tanto, se puede recoger de forma segura.

Si no está seguro de si algo se recogerá hágase la siguiente pregunta: ¿todavía existe una referencia a él? La instancia del objeto hace referencia a los controladores de eventos, no al revés.

 6
Author: lvaneenoo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-18 10:55:37

pClass será recogida de basura. Sin embargo, si el fragmento de código anterior está dentro de otra clase, es posible que la instancia de esa clase no se borre si no establece pClass a null.

 0
Author: Arav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-19 21:25:36