From 922cd9ebd6f9e44b30f7628914bde02c8680230b Mon Sep 17 00:00:00 2001 From: ggrote Date: Mon, 27 May 2013 13:37:50 +0200 Subject: [PATCH] Added InUseThreads to IWorkItemsGroup Also added a UnitTest for it. Thanks to TheCutter. --- STPTests/TestWIGConcurrencyChanges.cs | 101 +++++++++++--------------- SmartThreadPool/Interfaces.cs | 5 ++ SmartThreadPool/SmartThreadPool.cs | 24 +++--- SmartThreadPool/WorkItemsGroup.cs | 8 ++ SmartThreadPool/WorkItemsGroupBase.cs | 2 + 5 files changed, 70 insertions(+), 70 deletions(-) diff --git a/STPTests/TestWIGConcurrencyChanges.cs b/STPTests/TestWIGConcurrencyChanges.cs index 64dbc8f..93723cc 100644 --- a/STPTests/TestWIGConcurrencyChanges.cs +++ b/STPTests/TestWIGConcurrencyChanges.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Threading; using NUnit.Framework; @@ -13,9 +14,6 @@ namespace WorkItemsGroupTests [Category("TestWIGConcurrencyChanges")] public class TestWIGConcurrencyChanges { - /// - /// Example of waiting for idle - /// [Test] public void TestWIGConcurrencyChange1WIG() { @@ -57,9 +55,6 @@ namespace WorkItemsGroupTests smartThreadPool.Shutdown(); } - /// - /// Example of waiting for idle - /// [Test] public void TestWIGConcurrencyChange2WIGs() { @@ -141,67 +136,57 @@ namespace WorkItemsGroupTests return 1; } - - - -/* - /// - /// Example of waiting for idle - /// [Test] - public void WaitForIdle() - { - SmartThreadPool smartThreadPool = new SmartThreadPool(10*1000, 25, 0); + public void TestWIGConcurrencyChange() + { + SmartThreadPool smartThreadPool = new SmartThreadPool(10 * 1000, 25, 0); + IWorkItemsGroup wig = smartThreadPool.CreateWorkItemsGroup(smartThreadPool.MaxThreads); bool success = false; - for(int i = 0; i < 100; ++i) + for (int i = 0; i < 100; ++i) { - smartThreadPool.QueueWorkItem( - new WorkItemCallback(this.DoSomeWork), - null); + wig.QueueWorkItem(new WorkItemCallback(this.DoSomeLongWork), null); } - success = !smartThreadPool.WaitForIdle(3500); - success = success && smartThreadPool.WaitForIdle(1000); + wig.Concurrency = 1; + success = WaitForWIGThreadsInUse(wig, 1, 1 * 1000); + Assert.IsTrue(success); + + wig.Concurrency = 5; + success = WaitForWIGThreadsInUse(wig, 5, 2 * 1000); + Assert.IsTrue(success); + + wig.Concurrency = 25; + success = WaitForWIGThreadsInUse(wig, 25, 4 * 1000); + Assert.IsTrue(success); + + wig.Concurrency = 10; + success = WaitForWIGThreadsInUse(wig, 10, 10 * 1000); + Assert.IsTrue(success); smartThreadPool.Shutdown(); - - Assert.IsTrue(success); - } - - [Test] - public void WaitForIdleOnWrongThread() - { - SmartThreadPool smartThreadPool = new SmartThreadPool(10*1000, 25, 0); - - IWorkItemResult wir = smartThreadPool.QueueWorkItem( - new WorkItemCallback(this.DoWaitForIdle), - smartThreadPool); - - Exception e; - wir.GetResult(out e); - - smartThreadPool.Shutdown(); - - Assert.IsTrue(e is NotSupportedException); - } - - - private int x = 0; - private object DoSomeWork(object state) - { - Debug.WriteLine(Interlocked.Increment(ref x)); - Thread.Sleep(1000); - return 1; } - private object DoWaitForIdle(object state) - { - SmartThreadPool smartThreadPool = state as SmartThreadPool; - smartThreadPool.WaitForIdle(); - return null; - } - */ - } + + private bool WaitForWIGThreadsInUse(IWorkItemsGroup wig, int maxThreadsCount, int timeout) + { + DateTime end = DateTime.Now + new TimeSpan(0, 0, 0, 0, timeout); + + bool success = false; + while (DateTime.Now <= end && !success) + { + success = (wig.InUseThreads == maxThreadsCount); + Thread.Sleep(10); + } + + return success; + } + + private object DoSomeLongWork(object state) + { + Thread.Sleep(250); + return 1; + } + } } diff --git a/SmartThreadPool/Interfaces.cs b/SmartThreadPool/Interfaces.cs index a25a499..f23205d 100644 --- a/SmartThreadPool/Interfaces.cs +++ b/SmartThreadPool/Interfaces.cs @@ -84,6 +84,11 @@ namespace Amib.Threading /// int WaitingCallbacks { get; } + /// + /// Get the number of currently executing work items + /// + int InUseThreads { get; } + /// /// Get an array with all the state objects of the currently running items. /// The array represents a snap shot and impact performance. diff --git a/SmartThreadPool/SmartThreadPool.cs b/SmartThreadPool/SmartThreadPool.cs index a4f4ce5..fc25c21 100644 --- a/SmartThreadPool/SmartThreadPool.cs +++ b/SmartThreadPool/SmartThreadPool.cs @@ -1395,18 +1395,6 @@ namespace Amib.Threading } } - /// - /// Get the number of busy (not idle) threads in the thread pool. - /// - public int InUseThreads - { - get - { - ValidateNotDisposed(); - return _inUseWorkerThreads; - } - } - /// /// Returns true if the current running work item has been cancelled. /// Must be used within the work item's callback method. @@ -1508,6 +1496,18 @@ namespace Amib.Threading set { MaxThreads = value; } } + /// + /// Get the number of busy (not idle) threads in the thread pool. + /// + public override int InUseThreads + { + get + { + ValidateNotDisposed(); + return _inUseWorkerThreads; + } + } + /// /// Get the number of work items in the queue. /// diff --git a/SmartThreadPool/WorkItemsGroup.cs b/SmartThreadPool/WorkItemsGroup.cs index d9d34ac..a78c78c 100644 --- a/SmartThreadPool/WorkItemsGroup.cs +++ b/SmartThreadPool/WorkItemsGroup.cs @@ -126,6 +126,14 @@ namespace Amib.Threading.Internal } } + public override int InUseThreads + { + get + { + return _workItemsExecutingInStp; + } + } + public override int WaitingCallbacks { get { return _workItemsQueue.Count; } diff --git a/SmartThreadPool/WorkItemsGroupBase.cs b/SmartThreadPool/WorkItemsGroupBase.cs index b629c51..c6c0fdb 100644 --- a/SmartThreadPool/WorkItemsGroupBase.cs +++ b/SmartThreadPool/WorkItemsGroupBase.cs @@ -39,6 +39,8 @@ namespace Amib.Threading.Internal public abstract int Concurrency { get; set; } public abstract int WaitingCallbacks { get; } + public abstract int InUseThreads { get; } + public abstract object[] GetStates(); public abstract WIGStartInfo WIGStartInfo { get; } public abstract void Start();