简单ThreadPool实现2011-09-03 博客园 ITAres由于最近需要用多线程处理一些问题,一开始我用了.net默认的ThreadPool, 感觉不是很适合。于是我自己实现了一个简单的ThreadPool。写的比较简单,有兴趣的朋友一起看看,共同改进。代码主要由ThreadPoolEx,WorkItem,WorkQueue组成。ThreadPoolEx
1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5using System.Threading; 6using System.Collections; 7 8namespace 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 break; 97 } 98 } 99100 System.Threading.Thread.Sleep(100);101 }102 else103 {104105 try106 {107 _threadTable[Thread.CurrentThread] = System.DateTime.Now;108 Interlocked.Increment(ref _inUseWorkThread);109110 workItem.Execute();111 }112 catch (Exception)113 {114 // log something115 }116 finally117 {118 Interlocked.Decrement(ref _inUseWorkThread);119 }120 }121 }122 }123 catch (ThreadAbortException)124 {125 Thread.ResetAbort();126 }127 finally128 {129 if (_threadTable.Count > MinThreadCount)130 {131 _threadTable.Remove(Thread.CurrentThread);132 }133 }134 }135136 private bool CurThreadIsTimeOut()137 {138 DateTime lastAliveTime = (DateTime)_threadTable[Thread.CurrentThread];139140 DateTime curTime = System.DateTime.Now;141142 double waitSeconds = (curTime - lastAliveTime).TotalSeconds;143144 if(waitSeconds > IdleTimeout)145 {146 return true;147 }148149 return false;150151 }152153 private int _waitWorkItem154 {155 get156 {157 return _workQueue.Count;158 }159 }160161 public int ThreadCount162 {163 get164 {165 return _threadTable.Count;166 }167 }168 }169}170