Que se passe-t-il avec les gestionnaires d’événements lorsqu’un object sort du cadre?

Disons que nous avons la configuration suivante:

public class ClassA { public event EventHandler SomeEvent; } public class ClassB : IDisposable { public void SomeMethod(ClassA value) { value.SomeEvent += (s, e) => { DoSomething(); }; } void DoSomething() { } void Dispose() { } } public static class Program { static void Main() { var a = new ClassA(); using (var b = new ClassB()) b.SomeMethod(a); // POINT OF QUESTION!! } } 

Que se passe-t-il lorsque l’événement SomeEvent est SomeEvent après le “POINT DE QUESTION”?

Il appellera la méthode d’object éliminé. C’est pourquoi il est important de se désabonner. Cela peut même conduire à des memory leaks.

Rien de ce qui précède ne décrocherait votre gestionnaire d’événements. Puisque a et b sortent tous deux de la scope en même temps, vous seriez en sécurité. Puisque a et b peuvent être tous les deux rassemblés, alors a ne gardera pas b vie.

Si vous deviez générer l’événement ClassA.SomeEvent après votre instruction using, ClassB.DoSomething sera appelé même si b a été supprimé. Dans ce cas, vous devez explicitement supprimer le gestionnaire d’événements.

Si vous gardiez une référence à a autre endroit, alors b serait maintenu en vie par a . Encore une fois, car le gestionnaire d’événements n’a pas été supprimé.

Vous devez utiliser la méthode Dispose() de ClassB pour vous désabonner de l’événement ClassA. Vous courez le risque que les classes ne soient pas ramassées, ce qui bien sûr pourrait entraîner des memory leaks. Vous devriez toujours vous séparer des événements.

Rien. Runtime ne connaît pas la méthode Dispose et l’appel à cette méthode à l’intérieur d’une instruction ne fait rien pour la gestion de la mémoire.

La récupération de place concerne uniquement la gestion de la mémoire, mais IDisposable (et Finalizer ) concerne la gestion des ressources. Vous devez donc vous penser et l’implémenter manuellement (et correctement, par exemple, vous désabonner dans Dispose ).