Evite inscrições de evento duplicados em C #
-
03-07-2019 - |
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?
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.