由于最近需要用多线程处理一些问题,一开始我用了.net默认的ThreadPool,感觉不是很适合。于是我自己实现了一个简单的ThreadPool。
写的比较简单,有兴趣的朋友一起看看,共同改进。
代码主要由ThreadPoolEx,WorkItem,WorkQueue组成。
推荐使用新版本:http://www.cnblogs.com/ITAres/archive/2009/08/25/1553800.html

ThreadPoolEx
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Text;
5
using System.Threading;
6
using System.Collections;
7
8
namespace NetDragon.ThreadPoolEx
9

{
10
public class ThreadPoolEx
11
{
12
private WorkQueue _workQueue = new WorkQueue();
13
14
public int MaxThreadCount = 10;
15
public int MinThreadCount = 2;
16
private Hashtable _threadTable = null;
17
18
private int _threadCount = 0;
19
private int _inUseWorkThread = 0;
20
21
public double IdleTimeout = 10;
22
23
public ThreadPoolEx():this(10,2,2)
24
{
25
}
26
27
public ThreadPoolEx(int maxThreadCouont, int minThreadCount, int idleTimeout)
28
{
29
MaxThreadCount = maxThreadCouont;
30
31
MinThreadCount = minThreadCount;
32
33
IdleTimeout = idleTimeout;
34
35
_threadTable = Hashtable.Synchronized(new Hashtable(MaxThreadCount));
36
}
37
38
public void QueueUserWorkItem(WaitCallback waitCallback, object objParams)
39
{
40
EnqueueWorkItem(waitCallback, objParams);
41
}
42
43
private void EnqueueWorkItem(WaitCallback waitCallback,object objParams)
44
{
45
WorkItem workItem = new WorkItem()
{
46
47
WorkCallback = waitCallback,
48
ObjParams = objParams
49
};
50
51
_workQueue.Push(workItem);
52
53
if (_inUseWorkThread + _waitWorkItem > _threadTable.Count)
54
{
55
StartThread();
56
}
57
}
58
59
private void StartThread()
60
{
61
if (_threadTable.Count < MaxThreadCount)
62
{
63
++_threadCount;
64
65
Thread thread = new Thread(ProcessWorkItems);
66
67
thread.IsBackground = true;
68
69
thread.Name = "ThreadPoolEx #" + _threadCount;
70
71
thread.Priority = ThreadPriority.Normal;
72
73
_threadTable[thread] = System.DateTime.Now;
74
75
thread.Start();
76
}
77
}
78
79
private void ProcessWorkItems()
80
{
81
82
try
83
{
84
while (true)
85
{
86
WorkItem workItem = _workQueue.Pop();
87
88
if (workItem == null)
89
{
90
bool isTimeout = CurThreadIsTimeOut();
91
92
if (isTimeout)
93
{
94
if (_threadTable.Count > MinThreadCount)
95
{
96
_threadTable.Remove(Thread.CurrentThread);
97
break;
98
}
99
}
100
101
System.Threading.Thread.Sleep(100);
102
}
103
else
104
{
105
106
try
107
{
108
_threadTable[Thread.CurrentThread] = System.DateTime.Now;
109
Interlocked.Increment(ref _inUseWorkThread);
110
111
workItem.Execute();
112
}
113
catch (Exception)
114
{
115
// log something
116
}
117
finally
118
{
119
Interlocked.Decrement(ref _inUseWorkThread);
120
}
121
}
122
}
123
}
124
catch (ThreadAbortException)
125
{
126
Thread.ResetAbort();
127
}
128
finally
129
{
130
if (_threadTable.Contains(Thread.CurrentThread))
131
{
132
_threadTable.Remove(Thread.CurrentThread);
133
}
134
}
135
}
136
137
private bool CurThreadIsTimeOut()
138
{
139
DateTime lastAliveTime = (DateTime)_threadTable[Thread.CurrentThread];
140
141
DateTime curTime = System.DateTime.Now;
142
143
double waitSeconds = (curTime - lastAliveTime).TotalSeconds;
144
145
if(waitSeconds > IdleTimeout)
146
{
147
return true;
148
}
149
150
return false;
151
152
}
153
154
private int _waitWorkItem
155
{
156
get
157
{
158
return _workQueue.Count;
159
}
160
}
161
162
public int ThreadCount
163
{
164
get
165
{
166
return _threadTable.Count;
167
}
168
}
169
}
170
}
171

WorkItem
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Text;
5
using System.Threading;
6
7
namespace NetDragon.ThreadPoolEx
8

{
9
class WorkItem
10
{
11
public WaitCallback WorkCallback;
12
13
public object ObjParams;
14
15
public void Execute()
16
{
17
WorkCallback(ObjParams);
18
}
19
}
20
}
21

WorkQueue
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Text;
5
6
namespace NetDragon.ThreadPoolEx
7

{
8
class WorkQueue
9
{
10
private static object threadLock = new object();
11
12
private Queue<WorkItem> _workQueue = new Queue<WorkItem>();
13
14
public WorkItem Pop()
15
{
16
lock (threadLock)
17
{
18
if (_workQueue.Count > 0)
19
{
20
return _workQueue.Dequeue();
21
}
22
return null;
23
}
24
}
25
26
27
public void Push(WorkItem workItem)
28
{
29
lock (threadLock)
30
{
31
_workQueue.Enqueue(workItem);
32
33
}
34
}
35
36
public int Count
37
{
38
get
39
{
40
return _workQueue.Count;
41
}
42
}
43
}
44
}
45
源代码下载
简单线程池实现v2版本