annotate Util/WorkQueue.cs @ 66:b7bc27c6734e

Added WorkQueue class
author Ivo Smits <Ivo@UCIS.nl>
date Tue, 15 Oct 2013 16:22:54 +0200
parents
children 5d1b72ba44dc
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
66
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1 ???using System;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
2 using System.Collections.Generic;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
3 using System.Threading;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
4 using System.Windows.Forms;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
5 using SysThreadPool = System.Threading.ThreadPool;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
6
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
7 namespace UCIS.Util {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
8 public class WorkQueue : WorkQueue<MethodInvoker> {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
9 public WorkQueue() : base(Handler) { }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
10 private static void Handler(MethodInvoker item) { item(); }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
11 }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
12 public class WorkQueue<TWork> : IDisposable {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
13 Queue<TWork> queue = new Queue<TWork>();
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
14 Action<TWork> callback = null;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
15 int maxIdleWorkers = 0;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
16 int maxWorkers = 1;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
17 int idleWorkers = 0;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
18 int workers = 0;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
19
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
20 public Boolean UseFrameworkThreadpool { get; set; }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
21
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
22 public WorkQueue(Action<TWork> callback) {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
23 this.callback = callback;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
24 UseFrameworkThreadpool = true;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
25 }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
26 public void Dispose() {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
27 maxWorkers = 0;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
28 lock (queue) Monitor.PulseAll(queue);
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
29 }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
30
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
31 public int MaxIdleWorkers {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
32 get { return maxIdleWorkers; }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
33 set {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
34 maxIdleWorkers = value;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
35 lock (queue) Monitor.PulseAll(queue);
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
36 }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
37 }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
38 public int MaxWorkers {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
39 get { return maxWorkers; }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
40 set {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
41 maxWorkers = value;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
42 lock (queue) Monitor.PulseAll(queue);
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
43 }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
44 }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
45 public int TotalWorkers { get { return workers; } }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
46 public int IdleWorkers { get { return idleWorkers; } }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
47
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
48 public void Enqueue(TWork item) {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
49 lock (queue) {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
50 queue.Enqueue(item);
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
51 Monitor.Pulse(queue);
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
52 if (workers < maxWorkers && idleWorkers == 0) StartWorker();
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
53 }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
54 }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
55 public void Clear() { lock (queue) queue.Clear(); }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
56 public int Count { get { lock (queue) return queue.Count; } }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
57
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
58 private void StartWorker() {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
59 lock (queue) {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
60 if (workers >= maxWorkers) return;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
61 if (UseFrameworkThreadpool) {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
62 SysThreadPool.QueueUserWorkItem(Worker);
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
63 } else {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
64 (new Thread(Worker)).Start();
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
65 }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
66 workers++;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
67 }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
68 }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
69 private void RaiseEvent(Action<WorkQueue<TWork>> callback) {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
70 if (callback != null) callback(this);
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
71 }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
72 private void Worker(Object state) {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
73 while (true) {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
74 TWork item;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
75 lock (queue) {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
76 if (workers >= maxWorkers) {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
77 workers--;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
78 break;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
79 }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
80 if (queue.Count == 0) {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
81 if (idleWorkers >= maxIdleWorkers) {
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
82 workers--;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
83 queue.TrimExcess();
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
84 break;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
85 }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
86 idleWorkers++;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
87 Monitor.Wait(queue);
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
88 idleWorkers--;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
89 if (queue.Count == 0) continue;
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
90 }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
91 item = queue.Dequeue();
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
92 }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
93 callback(item);
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
94 }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
95 }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
96 }
b7bc27c6734e Added WorkQueue class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
97 }