Si tengo el siguiente código:
MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass = null;
¿Se recogerá pClass basura? ¿O pasará el rato 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;
c#
.net
event-handling
garbage-collection
Mark Ingram
fuente
fuente
Respuestas:
Para la pregunta específica "¿Se recolectará basura pClass?": La suscripción al evento no tiene ningún efecto en la recolección de pClass (como el 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 arriba) sea elegible para la recopilación, esto deja de ser un problema.
Tenga en cuenta que esto es unidireccional; es decir, si tenemos:
entonces "publicador" mantendrá "objetivo" vivo, pero "objetivo" no mantendrá vivo "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 fue 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.
Sin embargo, los eventos estáticos, por este motivo, son muy peligrosos cuando se usan con controladores basados en instancias.
fuente
WeakReference
, y en algunos casos, podría ser una buena idea, pero la mayoría de las veces será una buena idea.Sí, pClass será basura recolectada. La suscripción al evento no implica que exista ninguna referencia a pClass.
Y así no, no tendrá que separar el controlador para que se pueda recolectar basura de pClass.
fuente
En el momento en que ya no se hace referencia a un fragmento de memoria, se convierte en candidato para la recolección de basura. Cuando la instancia de su clase se sale del alcance, su programa ya no hace referencia a ella. Ya no se usa y, por lo tanto, se puede recoger de forma segura.
Si no está seguro de si se recolectará algo, hágase la siguiente pregunta: ¿existe alguna referencia al respecto? La instancia del objeto hace referencia a los controladores de eventos, no al revés.
fuente
pClass
Se recogerá la basura. Sin embargo, si el fragmento de código anterior está dentro de otra clase, la instancia de esa clase podría no borrarse si no se establecepClass
ennull
.fuente