簡単なタスクキュー
8346 ワード
同僚の依頼に応じて、キュー実行の目的を達成するために簡単なコードを書いた.Net 2.0(vs 2005)、コードは以下の通りです.
比較的簡単でキャンセルなどは考慮されておらず,またQueueTaskメソッドはWaitAlltTaskCompletedメソッドと同じスレッドで実行されるべきである.
1: /// <summary>
2: ///
3: /// </summary>
4: private readonly int maxConcurrentTask = 10;
5: /// <summary>
6: ///
7: /// </summary>
8: private readonly object semaphore = new object();
9: /// <summary>
10: ///
11: /// </summary>
12: private volatile int taskQueuing = 0;
13: /// <summary>
14: ///
15: /// </summary>
16: private volatile int taskRunning = 0;
17:
18: /// <summary>
19: ///
20: /// </summary>
21: /// <param name="task"> </param>
22: public void QueueTask(object task)
23: {
24: do
25: {
26: //
27: if (taskQueuing + taskRunning < maxConcurrentTask)
28: {
29: System.Threading.Interlocked.Increment(ref taskQueuing);
30: if (System.Threading.ThreadPool.QueueUserWorkItem(RunTask, task))
31: return;
32: System.Threading.Interlocked.Decrement(ref taskQueuing);
33: }
34: //
35: lock (semaphore)
36: System.Threading.Monitor.Wait(semaphore, 1000);
37: }
38: while (true);
39: }
40:
41: /// <summary>
42: ///
43: /// </summary>
44: public void WaitAllTaskCompleted()
45: {
46: while (taskQueuing > 0 && taskRunning > 0)
47: lock (semaphore)
48: if (taskQueuing > 0 && taskRunning > 0)
49: System.Threading.Monitor.Wait(semaphore, 1000);
50: }
51:
52: private void RunTask(object task)
53: {
54: try
55: {
56: System.Threading.Interlocked.Increment(ref taskRunning);
57: System.Threading.Interlocked.Decrement(ref taskQueuing);
58: RunTaskCore(task);
59: }
60: finally
61: {
62: System.Threading.Interlocked.Decrement(ref taskRunning);
63: //
64: lock (semaphore)
65: System.Threading.Monitor.Pulse(semaphore);
66: }
67: }
68:
69: protected virtual void RunTaskCore(object task)
70: {
71: // todo : RunTaskCore
72: }
比較的簡単でキャンセルなどは考慮されておらず,またQueueTaskメソッドはWaitAlltTaskCompletedメソッドと同じスレッドで実行されるべきである.