Question

Comment suggérez-vous le meilleur moyen d’éviter les doublons d’événements? si cette ligne de code s'exécute à deux endroits, l'événement sera exécuté deux fois. J'essaie d'éviter que des événements tiers ne s'abonnent deux fois.

theOBject.TheEvent += RunMyCode;

Je peux utiliser efficacement ce programme dans mon setter delegate ...

theOBject.TheEvent -= RunMyCode;
theOBject.TheEvent += RunMyCode;

mais est-ce la meilleure façon?

Était-ce utile?

La solution

Je pense que le moyen le plus efficace consiste à transformer votre événement en propriété et à lui ajouter des verrous d'accès concurrentiels, comme dans ce Exemple :

private EventHandler _theEvent;
private object _eventLock = new object();
public event EventHandler TheEvent
{
    add
    {
        lock (_eventLock) 
        { 
            _theEvent -= value; 
            _theEvent += value; 
        }
    }
    remove
    {
        lock (_eventLock) 
        { 
           _theEvent -= value; 
        }
    }
}

Autres conseils

J'ai déjà fait cela auparavant .... cela suppose qu'il est acceptable que le dernier abonné s'appelle ce qui s'appelle.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            MyObject my = new MyObject();
            my.Changed += new EventHandler(my_Changed);
            my.Changed += new EventHandler(my_Changed1);

            my.Update();
            Console.ReadLine();
        }

        static void my_Changed(object sender, EventArgs e)
        {
            Console.WriteLine("Hello");
        }
        static void my_Changed1(object sender, EventArgs e)
        {
            Console.WriteLine("Hello1");
        }
    }
    public class MyObject
    {
        public MyObject()
        {
        }
        private EventHandler ChangedEventHandler;
        public event EventHandler Changed
        {
            add
            {
                ChangedEventHandler = value;
            }
            remove
            {
                ChangedEventHandler -= value;
            }
        }
        public void Update()
        {
            OnChanged();
        }

        private void OnChanged()
        {
            if (ChangedEventHandler != null)
            {
                ChangedEventHandler(this, null);
            }
        }
    }
}

Votre code est-il multi-threadé? Le verrouillage des accès simultanés n’est nécessaire que lorsque son multi-threaded. Si ce n'est pas une surcharge.

En tant que tel, votre approche de désabonnement et d'abonnement est correcte.

Merci

Si vous possédez le source de la classe ofObject, vous avez accès à InvocationList de TheEvent. Vous pouvez implémenter votre propre accesseur add pour l'événement et vérifier avant d'ajouter.

Cependant, je pense que votre approche convient également.

J'utilise votre approche sauf un détail. Je pense que les événements doivent être abonnés lorsque vous créez une nouvelle instance d'abonné ou theObject, cela rend le code plus simple. Ainsi, tout ce dont vous avez besoin est simplement de surveiller attentivement la mise au rebut des objets appropriés (la solution à éliminer est une solution pratique pour cela).

Vous avez mentionné que vous utilisiez un événement tiers, ce qui signifie que vous ne pouvez pas fournir votre propre réalisation pour les méthodes d'ajout / suppression, comme vous en avez été informé. Mais dans vos propres classes avec vos propres événements, vous devez définir votre propre réalisation des méthodes d’ajout / suppression d’événement afin de résoudre votre problème.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top