C #: desencadenar un evento cuando un objeto se agrega a una cola

Necesito poder activar un evento cada vez que se agrega un objeto a una Queue .

Creé una nueva clase que extiende Queue :

 public delegate void ChangedEventHandler(object sender, EventArgs e); public class QueueWithChange : Queue { public event ChangedEventHandler Changed; protected virtual void OnChanged(EventArgs e) { if (Changed != null) { Changed(this, e); } } } 

Y luego adjuntó el evento de otra clase, como tal:

 QueueWithChange eventQueue = new QueueWithChange(); // eventQueue.Changed += new ChangedEventHandler(delegate(object s, EventArgs ex) { //This event is not being triggered, so this code is unreachable atm...and that is my problem if (eventQueue.Count > 0) { eventQueue.Dequeue().Invoke(new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(5) }); actionTimer.Stop(); } }); 

Pero cada vez que encola un objeto ( eventQueue.Enqueue(something) ), el evento adjunto no se activa.

¿Que me estoy perdiendo aqui?

Si te refieres a la clase Queue no genérica, entonces puedes anular Enqueue :

 public override void Enqueue(object obj) { base.Enqueue(obj); OnChanged(EventArgs.Empty); } 

Sin embargo, si se refiere a la clase genérica Queue , tenga en cuenta que no existe un método virtual adecuado para anular. Es posible que sea mejor encapsular la cola con su propia clase:

(** edición importante: eliminación de la clase base !!! **)

 class Foo { private readonly Queue queue = new Queue(); public event EventHandler Changed; protected virtual void OnChanged() { if (Changed != null) Changed(this, EventArgs.Empty); } public virtual void Enqueue(T item) { queue.Enqueue(item); OnChanged(); } public int Count { get { return queue.Count; } } public virtual T Dequeue() { T item = queue.Dequeue(); OnChanged(); return item; } } 

Sin embargo, mirando su código, parece posible que esté usando múltiples hilos aquí. Si ese es el caso, considere una cola de subprocesos en su lugar.

Acabo de escribir sobre lo que llamo TriggeredQueue. Ha inspirado la respuesta de Marc Gravell.

Puedes encontrar mi publicación aquí: http://joesauve.com/triggeredqueuet

Y el Gist aquí: http://gist.github.com/jsauve/b2e8496172fdabd370c4

Tiene cuatro eventos:

  • WillEnqueue
  • WillDequeue
  • DidEnqueue
  • DidDequeue

Puede enganchar en cualquiera de estos como sigue:

 YourQueue.WillEnqueue += (sender, e) => { // kick off some process }; YourQueue.DidEnqueue += (sender, e) => { // kick off some process // e.Item provides access to the enqueued item, if you like }; YourQueue.WillDequeue += (sender, e) => { // kick off some process }; YourQueue.DidDequeue += (sender, e) => { // kick off some process // e.Item provides access to the dequeued item, if you like }; 

Un buen truco es que puede usar el método DidDequeue para iniciar algún proceso y asegurarse de que la cola esté completa haciendo una solicitud web o cargando algunos datos de un sistema de archivos, etc. Utilizo esta clase en las aplicaciones móviles Xamarin para garantizar que los datos y las imágenes se almacenan previamente en la memoria caché para proporcionar una experiencia de usuario fluida, en lugar de cargar imágenes DESPUÉS de que se desplacen a la pantalla (como puede ver en Facebook y en innumerables otras aplicaciones).

tratar

 public new void Enqueue(Delegate d) { base.Enqueue(d); OnChanged(EventArgs.Empty); } 

Tienes que anular Enqueue, llamar a OnChanged.