Suppression de tous les gestionnaires d'événements en une seule fois
Problème: j'ai une classe de document qui contient une liste d'objets. Ces objets de déclencher des événements tels que SolutionExpired
, DisplayExpired
etc. Le document doit répondre à cette question.
Documents peuvent parfois échanger des objets, mais un seul objet ne doit jamais être une partie de plus d'un document.
Ma classe de document contient un ensemble de méthodes qui servent de gestionnaires d'événements. Chaque fois qu'un objet entre dans le document, j'utilise AddHandler
pour configurer les événements, et chaque fois qu'un objet est supprimé du document j'utilise RemoveHandler
pour réparer les dégâts. Cependant, il y a des cas où il est difficile de s'assurer que toutes les étapes sont correctement pris et je peut donc se retrouver avec rogue gestionnaires d'événements.
Longue histoire courte; comment puis-je supprimer tous les gestionnaires qui sont pointant sur une méthode spécifique? Remarque, je n'ai pas une liste de sources d'événements, ceux-ci pourraient être stockées n'importe où.
Quelque chose comme:
RemoveHandler *.SolutionExpired, AddressOf DefObj_SolutionExpired
Double Possible de Comment faire pour supprimer tous les événements à partir d'un contrôle
OriginalL'auteur David Rutten | 2009-07-19
Vous devez vous connecter pour publier un commentaire.
Vous pouvez utiliser
Delegate.RemoveAll()
. (La partie qui vous intéresse est dansbutton2_Click
)Vous devriez noter qu'il ne modifie pas le contenu des délégués de vous passer d'elle, elle renvoie une altération de son délégué. Par conséquent, vous ne serez pas en mesure de modifier les événements sur un bouton que vous venez de tomber sur un formulaire à partir de la forme, comme
button1.Click
ne peut avoir+=
ou-=
utilisé sur elle, pas=
. Ce ne compile pas:Aussi, assurez-vous que chaque fois que vous êtes à la mise en œuvre de ce que vous regardez pour le potentiel des conditions de course. Vous pourriez vous retrouver avec certains vraiment étrange comportement si vous êtes en train de retirer les gestionnaires d'un événement qui est appelé par un autre thread!
Aussi c'est C# alors que l'OP la question était de savoir vb.net. Alors que les deux ont beaucoup de chevauchement, cas la syntaxe est celle où ils diffèrent grandement dans
OriginalL'auteur Ben Lesh
EDIT 2: Excuses pour mon incompréhension, je vois que vous avez été assez clair au sujet de ne pas avoir accès à des sources d'événement dans votre post original.
Le moyen le plus simple je pense pour résoudre ce problème implique la mise en œuvre Partagée dictionnaire de l'objet-à-document de liaisons. Lorsqu'un objet entre dans un document, consultez le dictionnaire pour une liaison existante à un autre document; le cas échéant, retirez les gestionnaires qui font référence à l'ancien document avant de les ajouter à la nouvelle. De toute façon, mettre à jour le dictionnaire avec la nouvelle liaison.
Je pense que dans la plupart des cas, les performances et la mémoire impact serait négligeable: si vous avez affaire à plusieurs dizaines de milliers de petits objets et souvent de les échanger entre les documents, la surcharge de la mémoire de chaque paire clé/valeur et de performances pour chaque opération de recherche doit être relativement faible.
Comme une alternative: si vous pouvez détecter (dans le document de gestionnaires d'événements) que l'émetteur de l'événement n'est plus pertinente pour le document, vous pouvez détacher les événements.
Ceux-ci semblent comme le genre d'idées que vous pourriez avoir déjà rejeté--mais peut-être pas!
Je savais que j'aurais laissé l'original de la version C#. 🙂
Merci Ben, je vois ce que tu fais ici, mais si je ne me trompe pas cette fonction suppose que j'ai une référence à l'instance qui est d'élever les événements. Ces objets depuis longtemps disparu au-dessus de l'horizon dans une autre liste quelque part. Je commence à penser que ce n'est probablement pas possible de le faire depuis le gestionnaire de délégués sont définis dans la classe qui déclenche des événements, et non pas la classe qui définit le gestionnaire.
OriginalL'auteur Ben M
Utilisation
Délégué.RemoveAll
(peut-être l'aide de la réflexion si l'instance de Délégué est privé).OriginalL'auteur zproxy