Pergunta

Como você sugeriria a melhor maneira de evitar inscrições de evento duplicados? se esta linha de código é executado em dois lugares, o evento terá correu duas vezes. Estou tentando evitar eventos 3rd party de subscrever duas vezes.

theOBject.TheEvent += RunMyCode;

Na minha delegado setter, eu possa efetivamente executar este ...

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

mas é que a melhor maneira?

Foi útil?

Solução

Eu acho que, da maneira mais eficiente, é para tornar o evento uma propriedade e adicionar fechaduras de concorrência a ele como nesta Exemplo :

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

Outras dicas

Eu tenho feito isso antes .... ele assume que é aceitável que a última assinante é o que é chamado.

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

é o código multi-threaded? bloqueio de simultaneidade é necessário apenas quando a sua multi threaded. Se não é uma sobrecarga.

Como tal a sua abordagem de subscrição unsubscribing e está correto.

Graças

Se você possui a fonte para a classe de theObject, então você tem acesso ao InvocationList de TheEvent. Você pode implementar seu próprio assessor add para o evento e verificar antes de acrescentar.

No entanto, penso que a sua abordagem é muito fina.

Eu uso a sua abordagem, exceto um detalhe. Eu acho, que os eventos devem ser subscrito quando você cria nova instância do assinante ou theObject, o que torna o código mais reta. Assim, tudo o que você precisa é apenas observar cuidadosamente após objetos corretos eliminação (Patten descarte é solução conveniente para isso).

Você mencionou que você usa 3º evento do partido, o que significa que você não pode fornecer a sua própria realização de métodos de adicionar / remover, como você tem sido aconselhado. Mas, em suas próprias classes com seus próprios eventos você deve definir a sua própria realização de métodos de adicionar / remover para o evento, a fim de resolver seu problema.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top