Mercurial > hg > ucis.core
diff ThreadPool.cs @ 7:4b78cc5f116b
Fixes and improvements (some untested)
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Sun, 13 Jan 2013 18:44:17 +0100 |
parents | 3ab940a0c7a0 |
children | 1474f92cf7e7 |
line wrap: on
line diff
--- a/ThreadPool.cs Tue Jan 08 16:38:37 2013 +0100 +++ b/ThreadPool.cs Sun Jan 13 18:44:17 2013 +0100 @@ -1,6 +1,7 @@ using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Threading; -using System.Collections.Generic; namespace UCIS { public class ThreadPool { @@ -49,7 +50,7 @@ } private List<ThreadInfo> pThreads = new List<ThreadInfo>(); - private List<ThreadInfo> pBusyThreads = new List<ThreadInfo>(); + private int pBusyThreads = 0; private Queue<ThreadInfo> pIdleThreads = new Queue<ThreadInfo>(); private int pThreadsMax; private int pThreadsMinIdle; @@ -58,16 +59,11 @@ public event OnExceptionEventHandler OnException; public delegate void OnExceptionEventHandler(ThreadPool sender, ExceptionEventArgs e); - public System.Collections.ObjectModel.ReadOnlyCollection<ThreadInfo> Threads { - get { - return new System.Collections.ObjectModel.ReadOnlyCollection<ThreadInfo>(pThreads); - } - } + public ReadOnlyCollection<ThreadInfo> Threads { get { return pThreads.AsReadOnly(); } } - public ThreadPool() : this(250, 1, 5) { } + public ThreadPool() : this(250, 0, 5) { } public ThreadPool(int MaxThreads, int MinIdle, int MaxIdle) { - int I = 0; if (MaxThreads < 0) { throw new ArgumentOutOfRangeException("ThreadsMaxIdle", "ThreadsMaxIdle must greater than 0"); } else if (MaxThreads < MaxIdle) { @@ -82,20 +78,14 @@ pThreadsMax = MaxThreads; pThreadsMinIdle = MinIdle; pThreadsMaxIdle = MaxIdle; - for (I = 1; I <= pThreadsMinIdle; I++) { + for (int I = 1; I <= pThreadsMinIdle; I++) { StartThread(false); } } - public int ThreadsIdle { - get { return pIdleThreads.Count; } - } - public int ThreadsBusy { - get { return pBusyThreads.Count; } - } - public int ThreadsAlive { - get { return pThreads.Count; } - } + public int ThreadsIdle { get { return pIdleThreads.Count; } } + public int ThreadsBusy { get { return pBusyThreads; } } + public int ThreadsAlive { get { return pThreads.Count; } } public int ThreadsMinIdle { get { return pThreadsMinIdle; } set { @@ -119,62 +109,39 @@ public int ThreadsMaxIdle { get { return pThreadsMaxIdle; } set { - if (pThreadsMinIdle > value) { - throw new ArgumentOutOfRangeException("ThreadsMaxIdle", "ThreadsMaxIdle must be greater than or equal to ThreadsMinIdle"); - } else if (value < 0) { - throw new ArgumentOutOfRangeException("ThreadsMaxIdle", "ThreadsMaxIdle must greater than or equal to 0"); - } else { - int I = 0; - int C = 0; - ThreadInfo T = default(ThreadInfo); - lock (pIdleThreads) { - C = pIdleThreads.Count; - if (value < C) { - for (I = value; I <= C - 1; I++) { - T = pIdleThreads.Dequeue(); - T.Abort = true; - T.WaitHandle.Set(); - } - } + if (pThreadsMinIdle > value) throw new ArgumentOutOfRangeException("ThreadsMaxIdle", "ThreadsMaxIdle must be greater than or equal to ThreadsMinIdle"); + if (value < 0) throw new ArgumentOutOfRangeException("ThreadsMaxIdle", "ThreadsMaxIdle must greater than or equal to 0"); + lock (pIdleThreads) { + while (value > pIdleThreads.Count) { + ThreadInfo T = pIdleThreads.Dequeue(); + T.Abort = true; + T.WaitHandle.Set(); } - pThreadsMaxIdle = value; } + pThreadsMaxIdle = value; } } public int ThreadsMax { get { return pThreadsMax; } set { - if (pThreadsMaxIdle > value) { - throw new ArgumentOutOfRangeException("ThreadsMax", "ThreadsMax must be greater than or equal to ThreadsMaxIdle"); - } else if (value <= 0) { - throw new ArgumentOutOfRangeException("ThreadsMax", "ThreadsMax must greater than 0"); - } else { - pThreadsMax = value; - } + if (pThreadsMaxIdle > value) throw new ArgumentOutOfRangeException("ThreadsMax", "ThreadsMax must be greater than or equal to ThreadsMaxIdle"); + if (value <= 0) throw new ArgumentOutOfRangeException("ThreadsMax", "ThreadsMax must greater than 0"); + pThreadsMax = value; } } public WorkItem QueueWorkItem(WaitCallback Callback, object State) { - WorkItem WorkItem = new WorkItem(); + WorkItem WorkItem = new WorkItem() { Callback = Callback, State = State }; ThreadInfo Thread = null; - WorkItem.Callback = Callback; - WorkItem.State = State; lock (pIdleThreads) { - while (pIdleThreads.Count > 0) { + while (Thread == null && pIdleThreads.Count > 0) { Thread = pIdleThreads.Dequeue(); - if (!Thread.Abort) { - break; - } else { - Thread = null; - } + if (Thread.Abort) Thread = null; } } if (Thread == null) { - if (pThreads.Count < pThreadsMax) { - Thread = StartThread(true); - } else { - throw new ThreadStateException("Thread limit exceeded"); - } + if (pThreads.Count >= pThreadsMax) throw new ThreadStateException("Thread limit exceeded"); + Thread = StartThread(true); } Thread.LastActive = DateTime.Now; WorkItem.Thread = Thread; @@ -235,16 +202,13 @@ while (true) { if (Thread.WaitHandle == null) throw new ArgumentNullException("WaitHandle"); if (!Thread.WaitHandle.WaitOne(1000, false)) { - if (pBusyThreads.Count == 0) { - return; - } else { - continue; - } - } + if (pBusyThreads <= 0) return; + continue; + } if (Thread.Abort) break; Thread.Busy = true; - lock (pBusyThreads) pBusyThreads.Add(Thread); + Interlocked.Increment(ref pBusyThreads); try { if (Thread.WorkItem == null) throw new ArgumentNullException("WorkItem"); if (Thread.WorkItem.Callback == null) throw new ArgumentNullException("WorkItem.Callback"); @@ -262,7 +226,7 @@ throw new Exception("Unhandled exception in work item", e.Exception); } } finally { - lock (pBusyThreads) pBusyThreads.Remove(Thread); + Interlocked.Decrement(ref pBusyThreads); } Thread.WorkItem.Thread = null; Thread.WorkItem = null;