Domanda

Come consiglieresti il ??modo migliore per evitare abbonamenti duplicati agli eventi? se questa riga di codice viene eseguita in due punti, l'evento verrà eseguito due volte. Sto cercando di evitare che eventi di terze parti si iscrivano due volte.

theOBject.TheEvent += RunMyCode;

Nel mio setter delegato, posso effettivamente eseguire questo ...

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

ma è il modo migliore?

È stato utile?

Soluzione

Penso che, il modo più efficiente, sia rendere il tuo evento una proprietà e aggiungere blocchi di concorrenza come in questo Esempio :

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

Altri suggerimenti

L'ho già fatto prima .... si presume che sia accettabile che l'ultimo abbonato sia quello che viene chiamato.

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);
            }
        }
    }
}

Il tuo codice è multi thread? Il blocco della concorrenza è necessario solo quando è multi thread. Altrimenti è un sovraccarico.

Pertanto, il tuo approccio di annullamento dell'iscrizione e iscrizione è corretto.

Grazie

Se possiedi l'origine per la classe di theObject, hai accesso alla InvocationList di TheEvent. È possibile implementare il proprio accessorio access per l'evento e verificare prima di aggiungere.

Tuttavia, penso che anche il tuo approccio vada bene.

Uso il tuo approccio tranne un dettaglio. Penso che gli eventi dovrebbero essere sottoscritti quando si crea una nuova istanza dell'abbonato o l'Oggetto, questo rende il codice più semplice. Pertanto, tutto ciò che serve è solo guardare attentamente dopo aver smaltito gli oggetti corretti (smaltire patten è la soluzione conveniente per questo).

Hai menzionato che usi un evento di terze parti, ciò significa che non puoi fornire la tua realizzazione per i metodi di aggiunta / rimozione, come ti è stato consigliato. Ma nelle tue classi con i tuoi eventi dovresti definire la tua realizzazione di metodi di aggiunta / rimozione per eventi al fine di risolvere il tuo problema.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top