由于最近需要用多线程处理一些问题,一开始我用了.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![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
8
namespace NetDragon.ThreadPoolEx
9![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
10
public class ThreadPoolEx
11![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
12
private WorkQueue _workQueue = new WorkQueue();
13![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
public int MaxThreadCount = 10;
15
public int MinThreadCount = 2;
16
private Hashtable _threadTable = null;
17![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
18
private int _threadCount = 0;
19
private int _inUseWorkThread = 0;
20![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
21
public double IdleTimeout = 10;
22![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
23
public ThreadPoolEx():this(10,2,2)
24![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
25
}
26![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
27
public ThreadPoolEx(int maxThreadCouont, int minThreadCount, int idleTimeout)
28![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
29
MaxThreadCount = maxThreadCouont;
30![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
31
MinThreadCount = minThreadCount;
32![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
33
IdleTimeout = idleTimeout;
34![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
35
_threadTable = Hashtable.Synchronized(new Hashtable(MaxThreadCount));
36
}
37![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
38
public void QueueUserWorkItem(WaitCallback waitCallback, object objParams)
39![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
40
EnqueueWorkItem(waitCallback, objParams);
41
}
42![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
43
private void EnqueueWorkItem(WaitCallback waitCallback,object objParams)
44![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
45![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
WorkItem workItem = new WorkItem()
{
46
47
WorkCallback = waitCallback,
48
ObjParams = objParams
49
};
50![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
51
_workQueue.Push(workItem);
52![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
53
if (_inUseWorkThread + _waitWorkItem > _threadTable.Count)
54![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
55
StartThread();
56
}
57
}
58![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
59
private void StartThread()
60![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
61
if (_threadTable.Count < MaxThreadCount)
62![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
63
++_threadCount;
64![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
65
Thread thread = new Thread(ProcessWorkItems);
66![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
67
thread.IsBackground = true;
68![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
69
thread.Name = "ThreadPoolEx #" + _threadCount;
70![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
71
thread.Priority = ThreadPriority.Normal;
72![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
73
_threadTable[thread] = System.DateTime.Now;
74![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
75
thread.Start();
76
}
77
}
78![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
79
private void ProcessWorkItems()
80![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
81![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
82
try
83![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
84
while (true)
85![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
86
WorkItem workItem = _workQueue.Pop();
87![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
88
if (workItem == null)
89![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
90
bool isTimeout = CurThreadIsTimeOut();
91![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
92
if (isTimeout)
93![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
94
if (_threadTable.Count > MinThreadCount)
95![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
96
_threadTable.Remove(Thread.CurrentThread);
97
break;
98
}
99
}
100![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
101
System.Threading.Thread.Sleep(100);
102
}
103
else
104![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
105![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
106
try
107![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
108
_threadTable[Thread.CurrentThread] = System.DateTime.Now;
109
Interlocked.Increment(ref _inUseWorkThread);
110![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
111
workItem.Execute();
112
}
113
catch (Exception)
114![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
115
// log something
116
}
117
finally
118![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
119
Interlocked.Decrement(ref _inUseWorkThread);
120
}
121
}
122
}
123
}
124
catch (ThreadAbortException)
125![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
126
Thread.ResetAbort();
127
}
128
finally
129![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
130
if (_threadTable.Contains(Thread.CurrentThread))
131![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
132
_threadTable.Remove(Thread.CurrentThread);
133
}
134
}
135
}
136![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
137
private bool CurThreadIsTimeOut()
138![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
139
DateTime lastAliveTime = (DateTime)_threadTable[Thread.CurrentThread];
140![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
141
DateTime curTime = System.DateTime.Now;
142![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
143
double waitSeconds = (curTime - lastAliveTime).TotalSeconds;
144![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
145
if(waitSeconds > IdleTimeout)
146![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
147
return true;
148
}
149![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
150
return false;
151![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
152
}
153![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
154
private int _waitWorkItem
155![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
156
get
157![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
158
return _workQueue.Count;
159
}
160
}
161![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
162
public int ThreadCount
163![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
164
get
165![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
7
namespace NetDragon.ThreadPoolEx
8![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
9
class WorkItem
10![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
11
public WaitCallback WorkCallback;
12![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
public object ObjParams;
14![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
15
public void Execute()
16![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
6
namespace NetDragon.ThreadPoolEx
7![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
8
class WorkQueue
9![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
10
private static object threadLock = new object();
11![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
12
private Queue<WorkItem> _workQueue = new Queue<WorkItem>();
13![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
public WorkItem Pop()
15![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
16
lock (threadLock)
17![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
18
if (_workQueue.Count > 0)
19![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
20
return _workQueue.Dequeue();
21
}
22
return null;
23
}
24
}
25![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
26![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
27
public void Push(WorkItem workItem)
28![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
29
lock (threadLock)
30![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
31
_workQueue.Enqueue(workItem);
32![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
33
}
34
}
35![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
36
public int Count
37![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
38
get
39![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
40
return _workQueue.Count;
41
}
42
}
43
}
44
}
45
源代码下载
简单线程池实现v2版本