Welcome

首页 / 软件开发 / .NET编程技术 / 简单ThreadPool实现

简单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