Mercurial > hg > ucis.core
view Util/WorkQueue.cs @ 104:327be9216006
Improved PML code
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Sat, 11 Oct 2014 14:05:41 +0200 |
parents | 5d1b72ba44dc |
children |
line wrap: on
line source
???using System; using System.Collections.Generic; using System.Threading; using System.Windows.Forms; using SysThreadPool = System.Threading.ThreadPool; namespace UCIS.Util { public class WorkQueue : WorkQueue<MethodInvoker> { public WorkQueue() : base(Handler) { } private static void Handler(MethodInvoker item) { item(); } } public class WorkQueue<TWork> : IDisposable { Queue<TWork> queue = new Queue<TWork>(); Action<TWork> callback = null; int maxIdleWorkers = 0; int maxWorkers = 1; int idleWorkers = 0; int workers = 0; public Boolean UseFrameworkThreadpool { get; set; } public WorkQueue(Action<TWork> callback) { this.callback = callback; UseFrameworkThreadpool = true; } public void Dispose() { maxWorkers = 0; lock (queue) Monitor.PulseAll(queue); } public int MaxIdleWorkers { get { return maxIdleWorkers; } set { maxIdleWorkers = value; lock (queue) Monitor.PulseAll(queue); } } public int MaxWorkers { get { return maxWorkers; } set { maxWorkers = value; lock (queue) Monitor.PulseAll(queue); } } public int TotalWorkers { get { return workers; } } public int IdleWorkers { get { return idleWorkers; } } public void Enqueue(TWork item) { lock (queue) { queue.Enqueue(item); Monitor.Pulse(queue); if (workers < maxWorkers && idleWorkers == 0) StartWorker(); } } public void Clear() { lock (queue) queue.Clear(); } public int Count { get { lock (queue) return queue.Count; } } private void StartWorker() { lock (queue) { if (workers >= maxWorkers) return; if (UseFrameworkThreadpool) { SysThreadPool.QueueUserWorkItem(Worker); } else { (new Thread(Worker)).Start(); } workers++; } } private void RaiseEvent(Action<WorkQueue<TWork>> callback) { if (callback != null) callback(this); } private void Worker(Object state) { while (true) { TWork item; lock (queue) { if (workers > maxWorkers) { workers--; break; } if (queue.Count == 0) { if (idleWorkers > maxIdleWorkers) { workers--; queue.TrimExcess(); break; } idleWorkers++; Monitor.Wait(queue); idleWorkers--; if (queue.Count == 0) continue; } item = queue.Dequeue(); } callback(item); } } } }