Click here to Skip to main content
15,891,253 members
Articles / Programming Languages / C#
Article

Use PriorityQueue to fire timed repeatable events

Rate me:
Please Sign up or sign in to vote.
4.00/5 (4 votes)
25 Apr 20052 min read 31.2K   397   24   1
An article on using PriorityQueue to generate events for doing repeat actions, one off alarms, etc.

eventqueue.gif

Introduction

Occasionally, I find I have a need for asynchronous events to be queued and fired at a regular interval. The actual application in this case was asking a vehicle tracking system for a location fix every 15 seconds, for various vehicles, plus occasional polling of battery state. Previously, I had used the STL PriorityQueue to do a similar thing in C++ for a nuclear reprocessing plant monitoring system, where various sensors had to be polled at different intervals.

Background

I have used BenDi's PriorityQueue code which is, I have to say, superb! My Q class derives from his base BinaryPriorityQueue.

Using the code

There's a console app that shows how to use the code - obviously it's a bit naive and you would probably want to poll the queue using a worker thread, or even embed the thread in the Q object and have it raise a .NET type event when necessary.

To use the event queue, do this:

  • Build an event queue object:
    C#
    EventQueue q = new EventQueue();
  • Build some events to go in it...
    C#
    RepeatEvent reFive = 
        new RepeatEvent(DateTime.Now.AddSeconds(10), 5, 5, null);
    RepeatEvent reUnlimted = 
        new RepeatEvent(DateTime.Now.AddSeconds(5), -1, 20, null); 
    OneShotEvent oneShot = new OneShotEvent(DateTime.Now.AddSeconds(12), null);
  • Push them onto the queue.
    C#
    q.Push(reFive); 
    q.Push(reUnlimted); 
    q.Push(oneShot);
  • And run this code in a loop or a thread to access the events:
    C#
    while (q.Count != 0) 
    { 
        QueuedEvent qe = q.GetNextReadyEvent(); 
        if (qe != null) 
        { 
            if (qe.Payload != null) 
            { 
                // do something.... 
            }
            // and, re queue if neccesary 
            if (qe.ReQueue()) 
            { 
                q.Push(qe); 
            }
        } 
        Thread.Sleep(10); 
    }

Under the Hood

EventQueue derives from BinaryPriorityQueue:

C#
public class EventQueue : BinaryPriorityQueue

Constructor calls the base constructor passing in the comparer:

C#
public EventQueue() : base(new EventQueueComparer())

Pop and Peek are overloaded to cast result to QueuedEvent type:

C#
public new QueuedEvent Pop()
public new QueuedEvent Peek()

GetNextReadyEvent has a look using Peek, and if the event has fired, hauls it off:

C#
public QueuedEvent GetNextReadyEvent()
{
    QueuedEvent e = Peek();
    if (e != null && e.IsFired())
        return base.Pop() as QueuedEvent;
    else
        return null;
}

Abstract QueuedEvent class is the base class that all elements of the queue derive from:

C#
public abstract class QueuedEvent

All queued objects therefore have an 'IsFired' function:

C#
public bool IsFired()
{
    return (dtNextFiringTime < DateTime.Now);
}

RepeatEvent object derives from the abstract base and takes a quantity and an interval as parameters:

C#
public RepeatEvent(DateTime dt, int qty, 
       int interval, object payload) : base(dt, payload)

And in its re-queue function, it works out the next firing time and decrements the number of shots:

C#
public override bool ReQueue()
{
    if (iNumberOfShots != -1)
        iNumberOfShots--;
    dtNextFiringTime = dtNextFiringTime.AddSeconds(iInterval);
    return (iNumberOfShots != 0);
}

The comparer class speaks for itself, simply checks the NextFiringTime of two events:

C#
public class EventQueueComparer : IComparer
{
    public int Compare(object x, object y)
    {
        QueuedEvent xx = x as QueuedEvent;
        QueuedEvent yy = y as QueuedEvent;
        return xx.NextFiringTime.CompareTo(yy.NextFiringTime);
    }
}

I think that about covers it. Nice and simple - enjoy! :o)

History

1.0 - Original posting.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generaloooh! Pin
Goffkock16-Mar-09 23:40
Goffkock16-Mar-09 23:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.