suscribirse que programacion orientado instanciar eventos evento event delegados declarar c# .net events delegates lambda

c# - programacion - ¿Puede un delegado anónimo darse de baja de un evento una vez que haya sido despedido?



instanciar un evento c# (3)

A partir de C # 7.0, C # soporta funciones locales .

Las funciones locales son métodos privados de un tipo que están anidados en otro miembro. Sólo pueden ser llamados desde su miembro que contiene.

public void QueueNotAvailable() { void handler(object sender, EventArgs e) { // do something StateChanged -= handler; } StateChanged += handler; }

Me pregunto qué es la "mejor práctica" cuando le pido a un controlador de eventos que cancele su suscripción después de disparar una vez.

Para el 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 se les envía uno de todos modos. Lo que quiero poder hacer es permitir al usuario "poner en cola" un "No estoy disponible" tan pronto como sea posible esa operación.

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 separado dispara los eventos y este controlador en particular se ejecuta dos veces, no es un problema. Solicitar la misma función muy cerca es aceptable. Simplemente no quiero que se dispare cada vez que se permita la operación.


El enfoque, que Dean Harding sugiere funciona como un encanto, pero necesita agregar 2 líneas por evento y necesita un nombre por cada controlador, lo que hace que el código sea más complicado. Para evitar esto, puede escribir algún delegado inteligente como el siguiente:

public delegate void SmartAction<T>(SmartAction<T> self, T data); public event SmartAction<int> ProgressChanged; ProgressChanged += (self, progress) => { Console.WriteLine(progress); ProgressChanged -= self; };


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 ... tuve que poner el handler = null inicial handler = null allí, de lo contrario obtendré errores de compilación ''Uso de variable local no asignada'', pero creo que en realidad es benigno.