2010-06-21 25 views
16

Me pregunto cuál es la 'mejor práctica', cuando le pido a un controlador de eventos que se anule la suscripción después de disparar una vez.¿Puede un delegado anónimo darse de baja de un evento una vez que se ha activado?

Por contexto, esta es mi situación. Un usuario ha iniciado sesión y está listo para manejar elementos de trabajo. Reciben un elemento de trabajo, lo procesan y luego vuelven a estar listos. En este punto, es posible que quieran decir que no están disponibles para más elementos de trabajo, pero uno se les envía de todos modos. Lo que quiero poder hacer es permitir que el usuario 'ponga' una 'No estoy disponible' tan pronto como sea posible.

public event SomeHandler StateChanged = delegate {}; 

public void QueueNotAvailable() 
{ 
    StateChanged += (s,e) => { 
           if (e.CanGoNotAvailable) { 
            someObject.NotAvailable(); 
            StateChanged -= {thishandler}; 
           } 
          } 
} 

Para mis propósitos, si sucede que un hilo por separado desencadena los eventos y este controlador en particular se ejecuta dos veces, no es un problema. Solicitar la misma función muy juntos es aceptable. Simplemente no quiero que se active cada vez que se permite la operación.

Respuesta

39

Puede guardar una instancia del delegado antes de suscribirse al evento:

public void QueueNotAvailable() 
{ 
    SomeHandler handler = null; 
    handler = (s,e) { 
     // ... 
     StateChanged -= handler; 
    }; 
    StateChanged += handler; 
} 

Creo que esto debería hacerlo ... que tenía que poner la inicial handler = null allí de otro modo se obtiene el 'Uso de sin asignar errores de compilación de variables locales, pero creo que en realidad es benigno.

+0

Es genial que se pueda hacer referencia a sí mismo. Seguramente lo que estás diciendo aquí es "StateChanged - = null"? También tendría que tener el controlador almacenado en un miembro de nivel de clase, ya que supongo que el OP desea cambiar el estado StateChanged/handler de cada ejecución del controlador. –

+0

@Graphain: Quise decir en la línea 3, tengo 'SomeHandler handler = null;' - tuve que poner eso en línea por sí mismo (en lugar de asignarlo directamente al delegado anónimo) porque de lo contrario obtuve un error de compilación. No es necesario que sea un miembro de nivel de clase, ya que el cierre creado por el delegado anónimo simplemente lo hará ... –

+0

me doy cuenta de eso, pero me refiero a la línea 5 (ignorando el comentario), el controlador existiría como nulo cuando lo crea Supongo que tenemos suerte de que el código no se ejecuta hasta que el controlador está vinculado, por lo que no es un problema. Como me refiero a "a = null", entonces "a = (a + 1)" es en realidad "(a = (null + 1)" –

Cuestiones relacionadas