2009-11-11 3 views
1

Idéalement je veux une fonction quelque chose comme ce qui suit (cet exemple ne compile pas):C# Comment faire pour supprimer et nettoyer tous les événements

void AddRemoveEvent<TEvent, TArgs>(TEvent e, EventHandler<TArgs> h, bool add) 
     where TArgs : System.EventArgs 
    { 
     if (add) 
     { 
      e += h; 
     } 
     else 
     { 
      e -= h; 
     } 
    } 

Je peux écrire des fonctions:

void AddRemoveEvents(bool add) 
{ 
    AddRemoveEvent(aMemberControl.Click, OnClick, add); 
} 

I alors sais que je peux appeler à nouveau la fonction pour supprimer tous les gestionnaires. Je pense que ce serait mieux que d'écrire, en gardant et en comptant sur deux fonctions étant maintenues en synchronisation:

void AddEvents(bool add) 
{ 
    aMemberControl.Click += OnClick; 
} 

void RemoveEvents(bool add) 
{ 
    aMemberControl.Click -= OnClick; 
} 

Un collègue a écrit une classe à portée de main qui fait ce genre de choses qui utilise la réflexion. C'est très utile, mais cela dépend du nom de l'événement transmis en tant que chaîne. Je suis à la recherche d'un version de sécurité. Est-ce que quelqu'un a des idées sur s'il est possible d'écrire ceci?

Merci.

Je sais que je ne devrais pas vraiment avoir à désengorger des choses partout parce que le garbage collector devrait prendre soin de la plupart des cas. Mais, parfois, un événement parasite provoque une fuite, et donc je trouve qu'il est plus sûr d'essayer de supprimer tous les événements que j'ajoute plutôt que d'essayer de jouer avec un profileur en essayant d'identifier ceux qui causent des problèmes.

Je l'ai vu cette question connexe:
How to remove all event handlers from a control

Répondre

3

Vous ne pouvez pas le faire directement, malheureusement. Il n'y a pas d '"objet événement" disponible directement de manière sûre en C#. Vous pourriez le faire si vous aviez le EventInfo, mais vous devriez l'obtenir par son nom. Par exemple:

void AddRemoveEvent(object target, string name, Delegate handler, bool add) 
    where TArgs : System.EventArgs 
{ 
    EventInfo info = target.GetType().GetEvent(name); 
    // Error handling left as an exercise for the reader :) 
    if (add) 
    { 
     info.AddEventHandler(target, handler); 
    } 
    else 
    { 
     info.RemoveEventHandler(target, handler); 
    } 
} 

Pas très agréable :(

Je ne suis pas sûr que j'embêter avec cette méthode simple, en passant - je juste avoir AddEventHandler séparé et méthodes RemoveEventHandler Peut-être avoir. Une méthode courante pour extraire l'EventInfo, s'assurer qu'il existe et est du type approprié etc - mais pas un booléen pour indiquer ajouter/supprimer

1

Avec C# 3.5 les chaînes magiques peuvent dans un certain nombre de situations être remplacées par des arbres d'expression Il existe un certain nombre d'exemples flottant autour du besoin de passer une chaîne à l'événement PropertyChanged de INotifyPropertyChanged. ntNhibernate fait un bon usage de cette fonctionnalité pour pouvoir exprimer le comportement de la propriété d'un certain type.

Vous pouvez alors dire quelque chose comme Remove ((MyControlType t) => t.Click). Avec le code de l'autre poste Stackoverflow, vous vous en tirerez probablement sans spécifier les méthodes réelles étant le gestionnaire d'événements.

Questions connexes