C #: запуск события, когда объект добавляется в очередь - PullRequest
17 голосов
/ 10 февраля 2009

Мне нужно иметь возможность инициировать событие всякий раз, когда объект добавляется в Queue<Delegate>.

Я создал новый класс, который расширяет Queue:

public delegate void ChangedEventHandler(object sender, EventArgs e);

public class QueueWithChange<Delegate> : Queue<Delegate>
{
    public event ChangedEventHandler Changed;

    protected virtual void OnChanged(EventArgs e) {
        if (Changed != null)
        {
            Changed(this, e);
        }
    }
}

А потом прикрепил событие из другого класса, вот так:

QueueWithChange<TimerDelegate> eventQueue = new QueueWithChange<TimerDelegate>();

//

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

Но всякий раз, когда я ставлю объект в очередь (eventQueue.Enqueue(something)), присоединенное событие не запускается.

Что мне здесь не хватает?

Ответы [ 4 ]

30 голосов
/ 10 февраля 2009

Если вы имеете в виду неуниверсальный класс Queue, то вы можете просто переопределить Enqueue:

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

Однако, если вы имеете в виду универсальный класс Queue<T>, обратите внимание, что не существует подходящего виртуального метода для переопределения. Вы могли бы лучше инкапсулировать очередь с вашим собственным классом:

(** важное редактирование: удален базовый класс !!! **)

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

Однако, глядя на ваш код, кажется, что вы используете здесь несколько потоков. Если это так, рассмотрите очередь с резьбой .

4 голосов
/ 10 мая 2014

Я только что написал о том, что я называю TriggeredQueue. Это вдохновило ответ Марка Гравелла.

Мой пост можно найти здесь: http://joesauve.com/triggeredqueuet

И суть здесь: http://gist.github.com/jsauve/b2e8496172fdabd370c4

Это имеет четыре события:

  • WillEnqueue
  • WillDequeue
  • DidEnqueue
  • DidDequeue

Вы можете подключиться к любому из них следующим образом:

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

Одним из хитрых приемов является то, что вы можете использовать метод DidDequeue, чтобы запустить какой-то процесс, чтобы убедиться, что очередь заполнена, сделав веб-запрос или загрузив некоторые данные из файловой системы и т. Д. Я использую этот класс в мобильных приложениях Xamarin, чтобы убедитесь, что данные и изображения предварительно кэшируются для обеспечения бесперебойного взаимодействия с пользователем, вместо того, чтобы загружать изображения ПОСЛЕ того, как они прокручиваются на экран (как вы можете видеть в Facebook и бесчисленном количестве других приложений).

1 голос
/ 10 февраля 2009

1001 * попробовать *

public new void Enqueue(Delegate d)
{
    base.Enqueue(d);
    OnChanged(EventArgs.Empty);
}
0 голосов
/ 10 февраля 2009

Вы должны переопределить Enqueue, чтобы вызвать OnChanged.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...