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