2009-05-03 26 views
17

¿Cómo sugeriría la mejor manera de evitar suscripciones de eventos duplicados? si esta línea de código se ejecuta en dos lugares, el evento se ejecutará dos veces. Estoy tratando de evitar que los eventos de terceros se suscriban dos veces.Evite suscripciones de eventos duplicados en C#

theOBject.TheEvent += RunMyCode; 

En mi organismo delegado, que se puede ejecutar con eficacia este ...

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

pero es que la mejor manera?

Respuesta

19

Creo que, de la manera más eficiente, es hacer de su evento una propiedad y añadir cerraduras de concurrencia a ella como en este Example:

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

Dave Morton cambió su dominio. La nueva URL es: http://codinglight.blogspot.com/2009/02/preventing-duplicate-subscriptions-to.html –

+0

FYI, si obtiene un 503 en el enlace simplemente actualice la página. Pareció cargar después de algunos intentos por mí. – Dan

1

Si posee el código fuente de la clase del Objeto, entonces tiene acceso a InvocationList of TheEvent. Puede implementar su propio complemento de acceso para el evento y verificarlo antes de agregarlo.

Sin embargo, creo que su enfoque también está bien.

2

se enhebra su multi código? El bloqueo de simultaneidad solo se necesita cuando tiene múltiples hilos. Si no es una sobrecarga.

Como tal, su enfoque de darse de baja y suscribirse es correcto.

Gracias

0

Utilizo su enfoque excepto un detalle. Creo que los eventos deben suscribirse cuando se crea una nueva instancia de suscriptor u objeto, esto hace que el código sea más directo. Por lo tanto, todo lo que necesita es simplemente observar cuidadosamente después de deshacerse de los objetos correctos (disponer de Patten es una solución conveniente para esto).

Mencionó que usa un evento de terceros, lo que significa que no puede proporcionar su propia realización para métodos de agregar/quitar, como se le ha informado. Pero en sus propias clases con sus propios eventos, debe definir su propia realización de métodos de agregar/quitar eventos para resolver su problema.

4

He hecho esto antes ... asume que es aceptable que el último suscriptor sea el que se llame.

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

bueno, para aquellos lectores de velocidad que pueden haberlo perdido, esta es la línea importante. ChangedEventHandler = value; en lugar de + =. Bueno para un solo uso solamente - podría funcionar para mí en algunos casos - ¡gracias! – ScottCate

Cuestiones relacionadas