AsyncWorkQueue

Posts 12 of 2 · Page 1 of 1
AsyncWorkQueue
This is more of a placeholder so I can get this code when I get home, but figured I may as well share it.

Basically I needed an asynchronous work queue for downloading multiple files concurrently but with a limit imposed so that I didn't overload my computer. So I build a very simple AsyncWorkQueue class to internalize the process.

Code:
    public class AsyncWorkQueue<T>
    {
        private Queue<T> _queue; //internal queue.
        private int _max_concurrent; //maximum concurrent async work items.
        private int _concurrent; //current number of concurrent tasks.
        private int _completed; //current number of completed work items.
        
        public delegate void QueueCompletedHandler(); 
        public delegate void ItemDequeuedHandler(T obj); 

        public event QueueCompletedHandler OnQueueCompleted; //event fired when the _concurrent field hits zero (after at least 1 item has been added to the queue)
        public event ItemDequeuedHandler OnItemDequeued; //event fired when a new item is dequeued.

        public bool IsBusy { get; private set; } //whether the queue is currently processing async items.

        //Create a new AsyncWorkQueue, sets the maximum number of concurrent items
        //as well as the dequeue handler (when a new item is ready to be worked on)
        public AsyncWorkQueue(int concurrent_items, ItemDequeuedHandler dequeueHandler)
        {
            this._max_concurrent = concurrent_items;
            this._concurrent = 0;
            this._completed = 0;
            this._queue = new Queue<T>();
            this.IsBusy = false;

            this.OnItemDequeued = dequeueHandler; 
        }

        //Called when an item has finished being worked on. This is the responsibility of the developer
        //to call this whenever their async operation finishes.
        public void ItemCompleted()
        {
            this._concurrent--;
            this._completed++;
            if (this._concurrent == 0)
            {
                this.IsBusy = false;
                if (this.OnQueueCompleted != null)
                    this.OnQueueCompleted();
            }
            else
            {
                this.QueueAltered();
            }
        }

        // Add another item to the queue.
        public void Enqueue(T obj)
        {
            if (obj != null)
            {
                this._queue.Enqueue(obj);
                this.QueueAltered();
            }
        }

        //handle concurrency.
        private void QueueAltered()
        {
            if (this._concurrent < this._max_concurrent && this._queue.Count > 0)
            {
                this.IsBusy = true;
                this._concurrent++;
                T item = this._queue.Dequeue();

                if (this.OnItemDequeued != null)
                    this.OnItemDequeued(item);
            }
        }
    }
May be some issues with it, wrote it in like 15 minutes at work so mehz.
nice job + thanks. i will try it when i get on PC also :P
Posts 12 of 2 · Page 1 of 1

Post a Reply

Tags for this Thread

None

Need help?