/// <summary> /// Initializes the ThreadPool. Note: if the threadpool is configured for delayed /// initialization then threads aren't created until the the first work is added /// to the threadpool queue. /// </summary> private void Init() { LogInfo("ThreadPool.Init()"); _cancelWaitHandle.Reset(); ThreadPoolStartInfo.Validate(_startInfo); _inUseThreads = 0; _itemsProcessed = 0; if (!_startInfo.DelayedInit) { StartThreads(GetOptimalThreadCount()); } }
public void TestImmediateInit() { Console.Out.WriteLine("----=<TestImmediateInit>=----"); ThreadPoolStartInfo tpsi = new ThreadPoolStartInfo(); tpsi.MinimumThreads = 2; tpsi.MaximumThreads = 5; tpsi.ThreadIdleTimeout = 1000; tpsi.DelayedInit = false; _pool = new ThreadPool(tpsi); SetupLogging(); Assert.AreEqual(2, _pool.ThreadCount, "Thread count not 2; pool immediate initialization not OK"); _pool.Stop(); }
public void TestMaxThreadsLowerThanMin() { ThreadPoolStartInfo tpsi = new ThreadPoolStartInfo(10, 5); try { ThreadPoolStartInfo.Validate(tpsi); Assert.Fail("ArgumentOutOfRangeException not thrown"); } catch (ArgumentOutOfRangeException e) { Assert.IsTrue(e.ParamName == "MinimumThreads"); Assert.IsTrue(e.ActualValue is int, "ArgumentOutOfRangeException ActualValue is not of expected type"); Assert.AreEqual(10, (int)e.ActualValue); } }
/// <summary> /// Validates the given ThreadPoolStartInfo /// Throws ArgumentOutOutrangeException for MinimumThreads, MaximumThreads and /// ThreadIdleTimeout if they are invalid. /// </summary> /// <param name="tpsi">ThreadPoolStartInfo to validate</param> public static void Validate(ThreadPoolStartInfo tpsi) { if (tpsi.MinimumThreads < 1) { throw new ArgumentOutOfRangeException("MinimumThreads", tpsi.MinimumThreads, "cannot be less than one"); } if (tpsi.MaximumThreads < 1) { throw new ArgumentOutOfRangeException("MaximumThreads", tpsi.MaximumThreads, "cannot be less than one"); } if (tpsi.MinimumThreads > tpsi.MaximumThreads) { throw new ArgumentOutOfRangeException("MinimumThreads", tpsi.MinimumThreads, "must be less or equal to MaximumThreads"); } if (tpsi.ThreadIdleTimeout < 0) { throw new ArgumentOutOfRangeException("ThreadIdleTimeout", tpsi.ThreadIdleTimeout, "cannot be less than zero"); } }
public void TestValidParameters() { ThreadPoolStartInfo tpsi1 = new ThreadPoolStartInfo(30); ThreadPoolStartInfo tpsi2 = new ThreadPoolStartInfo(30, 31); ThreadPoolStartInfo tpsi3 = new ThreadPoolStartInfo(10, 25, 30000); ThreadPoolStartInfo tpsi4 = new ThreadPoolStartInfo(); tpsi4.DefaultThreadPriority = ThreadPriority.Lowest; try { ThreadPoolStartInfo.Validate(tpsi1); ThreadPoolStartInfo.Validate(tpsi2); ThreadPoolStartInfo.Validate(tpsi3); ThreadPoolStartInfo.Validate(tpsi4); Assert.AreEqual(30, tpsi1.MaximumThreads); } catch (ArgumentOutOfRangeException e) { Assert.Fail("Exception occurred while validating ThreadPoolStartInfo: message:{0} actualvalue:{1}", e.Message, e.ActualValue); } }
public void TestIntervalWork() { ThreadPoolStartInfo tpsi = new ThreadPoolStartInfo(2, 10, 1000); _pool = new ThreadPool(tpsi); SetupLogging(); IntervalWork iWork = new IntervalWork(new DoWorkHandler(delegate() { TestIntervalWorkRuns++; }), new TimeSpan(0, 0, 1)); iWork.Description = "TestIntervalWork"; _pool.AddIntervalWork(iWork, true); while (TestIntervalWorkRuns < 2) { Thread.Sleep(100); } _pool.RemoveIntervalWork(iWork); Assert.AreEqual(2, _pool.WorkItemsProcessed); }
public void TestWorkQueueLengthBusyCountAndWorkCancellation() { DoWorkHandler workHandler = new DoWorkHandler(delegate() { Thread.Sleep(300); }); Console.Out.WriteLine("----=<TestWorkItemsProcessed>=----"); List<IWork> workList = new List<IWork>(); ThreadPoolStartInfo tpsi = new ThreadPoolStartInfo(1, 1, 10); _pool = new ThreadPool(tpsi); SetupLogging(); _pool.Add(workHandler); Thread.Sleep(10); Assert.AreEqual(1, _pool.BusyThreadCount); for (int i = 0; i < 10; i++) { workList.Add(_pool.Add(workHandler)); } Assert.AreEqual(10, _pool.QueueLength); foreach (IWork work in workList) { work.State = WorkState.CANCELED; } _pool.MinimumThreads = _pool.MaximumThreads = 10; _pool.MinimumThreads = 0; while (_pool.BusyThreadCount > 0) { Thread.Sleep(100); } foreach (IWork work in workList) { Assert.AreEqual(WorkState.CANCELED, work.State); } Assert.AreEqual(0, _pool.QueueLength); Assert.AreEqual(0, _pool.BusyThreadCount); }
public void TestThreadCount() { Console.Out.WriteLine("----=<TestThreadCount>=----"); ThreadPoolStartInfo tpsi = new ThreadPoolStartInfo(); tpsi.MinimumThreads = 15; tpsi.DelayedInit = false; _pool = new ThreadPool(tpsi); Assert.AreEqual(15, _pool.ThreadCount); }
public void TestDropBackToMinThreads() { Console.Out.WriteLine("----=<TestDropBackToMinThreads>=----"); ThreadPoolStartInfo tpsi = new ThreadPoolStartInfo(2, 10, 100); _pool = new ThreadPool(tpsi); SetupLogging(); for (int i = 0; i < 10; i++) { _pool.Add(new DoWorkHandler(delegate() { Thread.Sleep(300); }), "TestDropBackToMinThreads" + i); Thread.Sleep(10); } Thread.Sleep(600); Assert.AreEqual(0, _pool.BusyThreadCount); Assert.AreEqual(10, _pool.WorkItemsProcessed); Assert.AreEqual(2, _pool.ThreadCount, "Pool did not drop back down to 2 threads"); _pool.Stop(); }
public void TestThreadIdleTimeoutOutOfRange() { ThreadPoolStartInfo tpsi = new ThreadPoolStartInfo(2, 5, -1); try { ThreadPoolStartInfo.Validate(tpsi); Assert.Fail("ArgumentOutOfRangeException not thrown"); } catch (ArgumentOutOfRangeException e) { Assert.IsTrue(e.ParamName == "ThreadIdleTimeout"); Assert.IsTrue(e.ActualValue is int, "ArgumentOutOfRangeException ActualValue is not of expected type"); Assert.AreEqual(-1, (int)e.ActualValue); } }
public ThreadPool(ThreadPoolStartInfo startInfo) { _startInfo = startInfo; Init(); }
public ThreadPool(int minThreads, int maxThreads) { _startInfo = new ThreadPoolStartInfo(minThreads, maxThreads); Init(); }