C#: Triggering an Event when an object is added to a Queue

前端 未结 4 1052
别跟我提以往
别跟我提以往 2020-11-29 02:13

I need to be able to trigger a event whenever an object is added to a Queue.

I created a new class that extends Q

相关标签:
4条回答
  • 2020-11-29 02:29

    If you mean the non-generic Queue class, then you can just override Enqueue:

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

    However, if you mean the generic Queue<T> class, then note that there is no suitable virtual method to override. You might do better to encapsulate the queue with your own class:

    (** important edit: removed base-class!!! **)

    class Foo<T>
    {
        private readonly Queue<T> queue = new Queue<T>();
        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;        
        }
    }
    

    However, looking at your code, it seems possible that you are using multiple threads here. If that is the case, consider a threaded queue instead.

    0 讨论(0)
  • 2020-11-29 02:40

    You have to override Enqueue, to call OnChanged.

    0 讨论(0)
  • 2020-11-29 02:45

    try

    public new void Enqueue(Delegate d)
    {
        base.Enqueue(d);
        OnChanged(EventArgs.Empty);
    }
    
    0 讨论(0)
  • 2020-11-29 02:48

    I just did write up on what I call a TriggeredQueue. It's inspired the answer by Marc Gravell.

    You can find my post here: http://joesauve.com/triggeredqueuet

    And the Gist here: http://gist.github.com/jsauve/b2e8496172fdabd370c4

    It has four events:

    • WillEnqueue
    • WillDequeue
    • DidEnqueue
    • DidDequeue

    You can hook into any of these like so:

    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
    };
    

    One neat trick is that you can use the DidDequeue method to kick off some process to ensure that the queue is full by making a web request or loading some data from a filesystem, etc. I use this class in Xamarin mobile apps to ensure that data and images are pre-cached in order to provide a smooth user experience, instead of loading images AFTER they scroll onto the screen (like you might see in Facebook and countless other apps).

    0 讨论(0)
提交回复
热议问题