web-dev-qa-db-fra.com

Les gestionnaires d'événements empêchent-ils la récupération de place de se produire?

Si j'ai le code suivant:

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

PClass sera-t-il récupéré? Ou va-t-il traîner en tirant toujours ses événements chaque fois qu'ils se produisent? Dois-je faire ce qui suit pour permettre la collecte des ordures?

MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass.MyEvent -= MyFunction;
pClass = null;
176
Mark Ingram

Pour la question spécifique "Est-ce que pClass sera récupéré": l'abonnement à l'événement n'a aucun effet sur la collecte de pClass (en tant qu'éditeur).

Pour GC en général (en particulier, la cible): cela dépend si MyFunction est statique ou basé sur une instance.

Un délégué (tel qu'un abonnement d'événement) à une méthode d'instance inclut une référence à l'instance. Alors oui, un abonnement à un événement empêchera GC. Cependant, dès que l'objet publiant l'événement (pClass ci-dessus) est éligible pour la collecte, cela cesse d'être un problème.

Notez que c'est unidirectionnel; c'est-à-dire si nous avons:

publisher.SomeEvent += target.SomeHandler;

alors "éditeur" gardera "cible" en vie, mais "cible" ne gardera pas "éditeur" en vie.

Donc non: si pClass va être collecté de toute façon, il n'est pas nécessaire de désinscrire les écouteurs. Cependant, si pClass a été de longue durée (plus longue que l'instance avec MyFunction), alors pClass pourrait garder cette instance en vie, il serait nécessaire de se désinscrire si vous voulez que la cible soit collectée.

Les événements statiques, cependant, pour cette raison, sont très dangereux lorsqu'ils sont utilisés avec des gestionnaires basés sur des instances.

196
Marc Gravell

Oui, pClass sera récupéré. L'abonnement à un événement n'implique pas qu'il existe une référence à pClass.

Et donc non, vous n'aurez pas à détacher le gestionnaire pour que pClass soit récupéré.

7
Tor Haugen

Dès qu'un morceau de mémoire n'est plus référencé, il devient un candidat pour la collecte des ordures. Lorsque l'instance de votre classe sort du domaine, elle n'est plus référencée par votre programme. Il n'est plus utilisé et peut donc être collecté en toute sécurité.

Si vous n'êtes pas sûr de savoir si quelque chose sera collecté, posez-vous la question suivante: existe-t-il encore une référence? Les gestionnaires d'événements sont référencés par l'instance d'objet, et non l'inverse.

7
lvaneenoo

pClass sera récupéré. Toutefois, si l'extrait de code ci-dessus se trouve dans une autre classe, l'instance de cette classe peut ne pas être supprimée si vous ne définissez pas pClass sur null.

0
Arav