SmartThreadPool v2.0
This commit is contained in:
Ami Bar
2009-12-19 16:32:41 +02:00
parent b30b4abdda
commit 4d6ffb5851
89 changed files with 13714 additions and 2639 deletions
+693
View File
@@ -0,0 +1,693 @@
using System.Threading;
using NUnit.Framework;
using Amib.Threading;
using System.Reflection;
#pragma warning disable 168
namespace SmartThreadPoolTests
{
public static class QueueWorkItemHelper
{
//IWorkItemResult QueueWorkItem(WorkItemCallback callback);
public static void TestQueueWorkItemCall(IWorkItemsGroup wig)
{
WorkItemInfo wii = new WorkItemInfo();
WorkItemInfoComparer wiic = new WorkItemInfoComparer(wii);
IWorkItemResult wir = wig.QueueWorkItem(wiic.CompareWorkItemInfo);
bool success = (bool)wir.Result;
Assert.IsTrue(success);
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback, WorkItemPriority workItemPriority);
public static void TestQueueWorkItemCallPrio(IWorkItemsGroup wig)
{
WorkItemInfo wii = new WorkItemInfo();
wii.WorkItemPriority = WorkItemPriority.AboveNormal;
WorkItemInfoComparer wiic = new WorkItemInfoComparer(wii);
IWorkItemResult wir = wig.QueueWorkItem((WorkItemCallback)wiic.CompareWorkItemInfo, WorkItemPriority.AboveNormal);
bool success = (bool)wir.Result;
Assert.IsTrue(success);
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state);
public static void TestQueueWorkItemCallStat(IWorkItemsGroup wig)
{
object state = new object();
WorkItemInfo wii = new WorkItemInfo();
WorkItemInfoComparer wiic = new WorkItemInfoComparer(wii, state);
IWorkItemResult wir = wig.QueueWorkItem((WorkItemCallback) wiic.CompareWorkItemInfo, state);
bool success = (bool)wir.Result;
Assert.IsTrue(success);
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, WorkItemPriority workItemPriority);
public static void TestQueueWorkItemCallStatPrio(IWorkItemsGroup wig)
{
object state = new object();
WorkItemInfo wii = new WorkItemInfo();
wii.WorkItemPriority = WorkItemPriority.AboveNormal;
WorkItemInfoComparer wiic = new WorkItemInfoComparer(wii, state);
IWorkItemResult wir = wig.QueueWorkItem(wiic.CompareWorkItemInfo, state, WorkItemPriority.AboveNormal);
bool success = (bool)wir.Result;
Assert.IsTrue(success);
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback);
public static void TestQueueWorkItemCallStatPost(IWorkItemsGroup wig)
{
bool postExecuteCalled = false;
object state = new object();
PostExecuteWorkItemCallback postExecuteWorkItemCallback = delegate(IWorkItemResult w) { postExecuteCalled = true; };
WorkItemInfo wii = new WorkItemInfo();
wii.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
WorkItemInfoComparer wiic = new WorkItemInfoComparer(wii, state);
IWorkItemResult wir = wig.QueueWorkItem(
wiic.CompareWorkItemInfo,
state,
postExecuteWorkItemCallback);
// We must wait for idle to let the post execute run
wig.WaitForIdle();
bool success = (bool)wir.Result;
Assert.IsTrue(success);
Assert.IsTrue(postExecuteCalled);
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, WorkItemPriority workItemPriority);
public static void TestQueueWorkItemCallStatPostPrio(IWorkItemsGroup wig)
{
bool postExecuteCalled = false;
object state = new object();
PostExecuteWorkItemCallback postExecuteWorkItemCallback = delegate(IWorkItemResult w) { postExecuteCalled = true; };
WorkItemInfo wii = new WorkItemInfo();
wii.WorkItemPriority = WorkItemPriority.BelowNormal;
wii.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
WorkItemInfoComparer wiic = new WorkItemInfoComparer(wii, state);
IWorkItemResult wir = wig.QueueWorkItem(
wiic.CompareWorkItemInfo,
state,
postExecuteWorkItemCallback,
WorkItemPriority.BelowNormal);
// We must wait for idle to let the post execute run
wig.WaitForIdle();
bool success = (bool)wir.Result;
Assert.IsTrue(success);
Assert.IsTrue(postExecuteCalled);
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute);
public static void TestQueueWorkItemCallStatPostPflg(IWorkItemsGroup wig)
{
bool postExecuteCalled;
CallToPostExecute callToPostExecute;
object state = new object();
PostExecuteWorkItemCallback postExecuteWorkItemCallback = delegate(IWorkItemResult w) { postExecuteCalled = true; };
WorkItemInfo wii = new WorkItemInfo();
wii.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
WorkItemInfoComparer wiic = new WorkItemInfoComparer(wii, state);
IWorkItemResult wir;
bool success;
/////////////////////////////////////////////////////////////////////////////
callToPostExecute = CallToPostExecute.Always;
// Check without cancel
postExecuteCalled = false;
wiic.SleepTime = 0;
wii.CallToPostExecute = callToPostExecute;
wir = wig.QueueWorkItem(
wiic.CompareWorkItemInfo,
state,
postExecuteWorkItemCallback,
callToPostExecute);
// We must wait for idle to let the post execute run
wig.WaitForIdle();
success = (bool)wir.Result;
Assert.IsTrue(success);
Assert.IsTrue(postExecuteCalled);
// Check with cancel
success = false;
postExecuteCalled = false;
wiic.SleepTime = 100;
wir = wig.QueueWorkItem(
wiic.CompareWorkItemInfo,
state,
postExecuteWorkItemCallback,
callToPostExecute);
wir.Cancel();
// We must wait for idle to let the post execute run
wig.WaitForIdle();
Assert.IsTrue(postExecuteCalled);
try
{
wir.GetResult();
}
catch (WorkItemCancelException ce)
{
success = true;
}
Assert.IsTrue(success);
/////////////////////////////////////////////////////////////////////////////
callToPostExecute = CallToPostExecute.Never;
postExecuteCalled = false;
wiic.SleepTime = 0;
wii.CallToPostExecute = callToPostExecute;
wir = wig.QueueWorkItem(
wiic.CompareWorkItemInfo,
state,
postExecuteWorkItemCallback,
callToPostExecute);
// We must wait for idle to let the post execute run
wig.WaitForIdle();
success = (bool)wir.Result;
Assert.IsTrue(success);
Assert.IsFalse(postExecuteCalled);
// Check with cancel
success = false;
postExecuteCalled = false;
wiic.SleepTime = 100;
wir = wig.QueueWorkItem(
wiic.CompareWorkItemInfo,
state,
postExecuteWorkItemCallback,
callToPostExecute);
wir.Cancel();
// We must wait for idle to let the post execute run
wig.WaitForIdle();
Assert.IsFalse(postExecuteCalled);
try
{
wir.GetResult();
}
catch (WorkItemCancelException ce)
{
success = true;
}
Assert.IsTrue(success);
/////////////////////////////////////////////////////////////////////////////
callToPostExecute = CallToPostExecute.WhenWorkItemNotCanceled;
postExecuteCalled = false;
wiic.SleepTime = 0;
wii.CallToPostExecute = callToPostExecute;
wir = wig.QueueWorkItem(
wiic.CompareWorkItemInfo,
state,
postExecuteWorkItemCallback,
callToPostExecute);
// We must wait for idle to let the post execute run
wig.WaitForIdle();
success = (bool)wir.Result;
Assert.IsTrue(success);
Assert.IsTrue(postExecuteCalled);
// Check with cancel
success = false;
postExecuteCalled = false;
wiic.SleepTime = 100;
wir = wig.QueueWorkItem(
wiic.CompareWorkItemInfo,
state,
postExecuteWorkItemCallback,
callToPostExecute);
wir.Cancel();
// We must wait for idle to let the post execute run
wig.WaitForIdle();
Assert.IsFalse(postExecuteCalled);
try
{
wir.GetResult();
}
catch (WorkItemCancelException ce)
{
success = true;
}
Assert.IsTrue(success);
/////////////////////////////////////////////////////////////////////////////
callToPostExecute = CallToPostExecute.WhenWorkItemCanceled;
postExecuteCalled = false;
wiic.SleepTime = 0;
wii.CallToPostExecute = callToPostExecute;
wir = wig.QueueWorkItem(
wiic.CompareWorkItemInfo,
state,
postExecuteWorkItemCallback,
callToPostExecute);
// We must wait for idle to let the post execute run
wig.WaitForIdle();
success = (bool)wir.Result;
Assert.IsTrue(success);
Assert.IsFalse(postExecuteCalled);
// Check with cancel
success = false;
postExecuteCalled = false;
wiic.SleepTime = 100;
wir = wig.QueueWorkItem(
wiic.CompareWorkItemInfo,
state,
postExecuteWorkItemCallback,
callToPostExecute);
wir.Cancel();
// We must wait for idle to let the post execute run
wig.WaitForIdle();
Assert.IsTrue(postExecuteCalled);
try
{
wir.GetResult();
}
catch (WorkItemCancelException ce)
{
success = true;
}
Assert.IsTrue(success);
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute, WorkItemPriority workItemPriority);
public static void TestQueueWorkItemCallStatPostPflgPrio(IWorkItemsGroup wig)
{
bool postExecuteCalled;
CallToPostExecute callToPostExecute;
object state = new object();
PostExecuteWorkItemCallback postExecuteWorkItemCallback = delegate(IWorkItemResult w) { postExecuteCalled = true; };
WorkItemInfo wii = new WorkItemInfo();
wii.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
WorkItemInfoComparer wiic = new WorkItemInfoComparer(wii, state);
WorkItemPriority workItemPriority;
IWorkItemResult wir;
bool success;
/////////////////////////////////////////////////////////////////////////////
callToPostExecute = CallToPostExecute.Always;
workItemPriority = WorkItemPriority.Lowest;
// Check without cancel
postExecuteCalled = false;
wiic.SleepTime = 0;
wii.CallToPostExecute = callToPostExecute;
wii.WorkItemPriority = workItemPriority;
wir = wig.QueueWorkItem(
wiic.CompareWorkItemInfo,
state,
postExecuteWorkItemCallback,
callToPostExecute,
workItemPriority);
// We must wait for idle to let the post execute run
wig.WaitForIdle();
success = (bool)wir.Result;
Assert.IsTrue(success);
Assert.IsTrue(postExecuteCalled);
// Check with cancel
success = false;
postExecuteCalled = false;
wiic.SleepTime = 100;
wir = wig.QueueWorkItem(
wiic.CompareWorkItemInfo,
state,
postExecuteWorkItemCallback,
callToPostExecute,
workItemPriority);
wir.Cancel();
// We must wait for idle to let the post execute run
wig.WaitForIdle();
Assert.IsTrue(postExecuteCalled);
try
{
wir.GetResult();
}
catch (WorkItemCancelException ce)
{
success = true;
}
Assert.IsTrue(success);
/////////////////////////////////////////////////////////////////////////////
callToPostExecute = CallToPostExecute.Never;
workItemPriority = WorkItemPriority.Highest;
postExecuteCalled = false;
wiic.SleepTime = 0;
wii.CallToPostExecute = callToPostExecute;
wii.WorkItemPriority = workItemPriority;
wir = wig.QueueWorkItem(
wiic.CompareWorkItemInfo,
state,
postExecuteWorkItemCallback,
callToPostExecute,
workItemPriority);
// We must wait for idle to let the post execute run
wig.WaitForIdle();
success = (bool)wir.Result;
Assert.IsTrue(success);
Assert.IsFalse(postExecuteCalled);
// Check with cancel
success = false;
postExecuteCalled = false;
wiic.SleepTime = 100;
wir = wig.QueueWorkItem(
wiic.CompareWorkItemInfo,
state,
postExecuteWorkItemCallback,
callToPostExecute,
workItemPriority);
wir.Cancel();
// We must wait for idle to let the post execute run
wig.WaitForIdle();
Assert.IsFalse(postExecuteCalled);
try
{
wir.GetResult();
}
catch (WorkItemCancelException ce)
{
success = true;
}
Assert.IsTrue(success);
/////////////////////////////////////////////////////////////////////////////
callToPostExecute = CallToPostExecute.WhenWorkItemNotCanceled;
workItemPriority = WorkItemPriority.AboveNormal;
postExecuteCalled = false;
wiic.SleepTime = 0;
wii.CallToPostExecute = callToPostExecute;
wii.WorkItemPriority = workItemPriority;
wir = wig.QueueWorkItem(
wiic.CompareWorkItemInfo,
state,
postExecuteWorkItemCallback,
callToPostExecute,
workItemPriority);
// We must wait for idle to let the post execute run
wig.WaitForIdle();
success = (bool)wir.Result;
Assert.IsTrue(success);
Assert.IsTrue(postExecuteCalled);
// Check with cancel
success = false;
postExecuteCalled = false;
wiic.SleepTime = 100;
wir = wig.QueueWorkItem(
wiic.CompareWorkItemInfo,
state,
postExecuteWorkItemCallback,
callToPostExecute,
workItemPriority);
wir.Cancel();
// We must wait for idle to let the post execute run
wig.WaitForIdle();
Assert.IsFalse(postExecuteCalled);
try
{
wir.GetResult();
}
catch (WorkItemCancelException ce)
{
success = true;
}
Assert.IsTrue(success);
/////////////////////////////////////////////////////////////////////////////
callToPostExecute = CallToPostExecute.WhenWorkItemCanceled;
workItemPriority = WorkItemPriority.BelowNormal;
postExecuteCalled = false;
wiic.SleepTime = 0;
wii.CallToPostExecute = callToPostExecute;
wii.WorkItemPriority = workItemPriority;
wir = wig.QueueWorkItem(
wiic.CompareWorkItemInfo,
state,
postExecuteWorkItemCallback,
callToPostExecute,
workItemPriority);
// We must wait for idle to let the post execute run
wig.WaitForIdle();
success = (bool)wir.Result;
Assert.IsTrue(success);
Assert.IsFalse(postExecuteCalled);
// Check with cancel
success = false;
postExecuteCalled = false;
wiic.SleepTime = 100;
wir = wig.QueueWorkItem(
wiic.CompareWorkItemInfo,
state,
postExecuteWorkItemCallback,
callToPostExecute,
workItemPriority);
wir.Cancel();
// We must wait for idle to let the post execute run
wig.WaitForIdle();
Assert.IsTrue(postExecuteCalled);
try
{
wir.GetResult();
}
catch (WorkItemCancelException ce)
{
success = true;
}
Assert.IsTrue(success);
}
//IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback);
public static void TestQueueWorkItemInfoCall(IWorkItemsGroup wig)
{
WorkItemInfo wii = new WorkItemInfo();
wii.CallToPostExecute = CallToPostExecute.Never;
wii.DisposeOfStateObjects = true;
wii.PostExecuteWorkItemCallback = delegate(IWorkItemResult w) { };
wii.UseCallerCallContext = true;
wii.UseCallerHttpContext = true;
wii.WorkItemPriority = WorkItemPriority.Highest;
WorkItemInfoComparer wiic = new WorkItemInfoComparer(wii);
IWorkItemResult wir = wig.QueueWorkItem(wii, wiic.CompareWorkItemInfo);
// We must wait for idle to let the post execute run
wig.WaitForIdle();
bool success = (bool)wir.Result;
Assert.IsTrue(success);
}
//IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state);
public static void TestQueueWorkItemInfoCallStat(IWorkItemsGroup wig)
{
object state = new object();
WorkItemInfo wii = new WorkItemInfo();
wii.CallToPostExecute = CallToPostExecute.Never;
wii.DisposeOfStateObjects = true;
wii.PostExecuteWorkItemCallback = delegate(IWorkItemResult w) { };
wii.UseCallerCallContext = true;
wii.UseCallerHttpContext = true;
wii.WorkItemPriority = WorkItemPriority.Highest;
WorkItemInfoComparer wiic = new WorkItemInfoComparer(wii, state);
IWorkItemResult wir = wig.QueueWorkItem(wii, wiic.CompareWorkItemInfo, state);
// We must wait for idle to let the post execute run
wig.WaitForIdle();
bool success = (bool)wir.Result;
Assert.IsTrue(success);
}
private static WorkItemInfo GetCurrentWorkItemInfo()
{
object threadEntry = typeof(SmartThreadPool).GetField("_threadEntry", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null);
object workitem = threadEntry.GetType().GetField("_currentWorkItem", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(threadEntry);
WorkItemInfo wii = (WorkItemInfo)workitem.GetType().GetField("_workItemInfo", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(workitem);
return wii;
}
private class WorkItemInfoComparer
{
private WorkItemInfo _neededWorkItemInfo;
private object _state;
private int _sleepTime = 0;
public int SleepTime
{
get { return _sleepTime; }
set { _sleepTime = value; }
}
public WorkItemInfoComparer(WorkItemInfo workItemInfo)
{
_neededWorkItemInfo = workItemInfo;
_state = null;
}
public WorkItemInfoComparer(WorkItemInfo workItemInfo, object state)
{
_neededWorkItemInfo = workItemInfo;
_state = state;
}
public object CompareWorkItemInfo(object state)
{
bool equals = object.Equals(_state, state);
if (equals)
{
WorkItemInfo currentWorkItemInfo = GetCurrentWorkItemInfo();
equals = CompareWorkItemInfo(currentWorkItemInfo, _neededWorkItemInfo);
}
if (_sleepTime > 0)
{
Thread.Sleep(_sleepTime);
}
return equals;
}
private bool CompareWorkItemInfo(WorkItemInfo wii1, WorkItemInfo wii2)
{
bool equal = true;
equal = equal && (wii1.CallToPostExecute == wii2.CallToPostExecute);
equal = equal && (wii1.DisposeOfStateObjects == wii2.DisposeOfStateObjects);
equal = equal && (wii1.PostExecuteWorkItemCallback == wii2.PostExecuteWorkItemCallback);
equal = equal && (wii1.UseCallerCallContext == wii2.UseCallerCallContext);
equal = equal && (wii1.UseCallerHttpContext == wii2.UseCallerHttpContext);
equal = equal && (wii1.WorkItemPriority == wii2.WorkItemPriority);
return equal;
}
}
}
}
+27 -3
View File
@@ -60,7 +60,7 @@
<DefineConstants>TRACE</DefineConstants>
<DocumentationFile>
</DocumentationFile>
<DebugSymbols>false</DebugSymbols>
<DebugSymbols>true</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<NoStdLib>false</NoStdLib>
<NoWarn>
@@ -70,11 +70,21 @@
<RemoveIntegerChecks>false</RemoveIntegerChecks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningLevel>4</WarningLevel>
<DebugType>none</DebugType>
<DebugType>full</DebugType>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseCE|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\ReleaseCE\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<BaseAddress>285212672</BaseAddress>
<Optimize>true</Optimize>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<ItemGroup>
<Reference Include="nunit.framework, Version=2.2.5.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />
<Reference Include="nunit.framework, Version=2.2.8.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />
<Reference Include="System">
<Name>System</Name>
</Reference>
@@ -94,12 +104,26 @@
<Compile Include="AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="TestFalseFillStateWithParams.cs" />
<Compile Include="TestFillStateWithParams.cs" />
<Compile Include="TestWIGFillStateWithParams.cs" />
<Compile Include="TestWIGActionT.cs" />
<Compile Include="TestWIGFuncT.cs" />
<Compile Include="TestActionT.cs" />
<Compile Include="TestFuncT.cs" />
<Compile Include="TestWIGQueueWorkItem.cs" />
<Compile Include="QueueWorkItemHelper.cs" />
<Compile Include="TestQueueWorkItem.cs" />
<Compile Include="TestCancel.cs" />
<Compile Include="TestConcurrencyChanges.cs" />
<Compile Include="PermutationGenerator.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="TestChainedDelegates.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="TestThreadsCreate.cs" />
<Compile Include="TestWIGConcurrencyChanges.cs" />
<Compile Include="TestExceptions.cs">
<SubType>Code</SubType>
</Compile>
+124
View File
@@ -0,0 +1,124 @@
using Amib.Threading;
using NUnit.Framework;
namespace SmartThreadPoolTests
{
/// <summary>
/// Summary description for TestCancel.
/// </summary>
[TestFixture]
[Category("TestActionT")]
public class TestActionT
{
private SmartThreadPool _stp;
private object _result;
[SetUp]
public void Init()
{
_stp = new SmartThreadPool();
}
[TearDown]
public void Fini()
{
_stp.Shutdown();
}
[Test]
public void ActionT0()
{
_result = null;
IWorkItemResult wir = _stp.QueueWorkItem(MaxInt);
wir.GetResult();
Assert.AreEqual(_result, int.MaxValue);
}
[Test]
public void ActionT1()
{
_result = null;
IWorkItemResult wir = _stp.QueueWorkItem(Not, true);
wir.GetResult();
Assert.AreEqual(_result, false);
}
[Test]
public void ActionT2()
{
_result = null;
IWorkItemResult wir = _stp.QueueWorkItem(Concat, "ABC", "xyz");
wir.GetResult();
Assert.AreEqual(_result, "ABCxyz");
}
[Test]
public void ActionT3()
{
_result = null;
IWorkItemResult wir = _stp.QueueWorkItem(Substring, "ABCDEF", 1, 2);
wir.GetResult();
Assert.AreEqual(_result, "BC");
}
[Test]
public void ActionT4()
{
_result = null;
int[] numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
IWorkItemResult wir = _stp.QueueWorkItem(Subarray, numbers, 1, 2, 3);
wir.GetResult();
Assert.AreEqual(_result, new int[] { 2, 3, 2, 3, 2, 3, });
}
private void MaxInt()
{
_result = int.MaxValue;
}
private void Not(bool flag)
{
_result = !flag;
}
private void Concat(string s1, string s2)
{
_result = s1 + s2;
}
private void Substring(string s, int startIndex, int length)
{
_result = s.Substring(startIndex, length);
}
private void Subarray(int[] numbers, int startIndex, int length, int repeat)
{
int[] result = new int[length * repeat];
for (int i = 0; i < repeat; i++)
{
for (int j = 0; j < length; j++)
{
result[i * length + j] = numbers[startIndex + j];
}
}
_result = result;
}
}
}
+806
View File
@@ -0,0 +1,806 @@
using System;
using System.Threading;
using NUnit.Framework;
using Amib.Threading;
namespace SmartThreadPoolTests
{
/// <summary>
/// Summary description for TestCancel.
/// </summary>
[TestFixture]
[Category("TestCancel")]
public class TestCancel
{
/// <summary>
/// 1. Create STP in suspended mode
/// 2. Queue work item into the STP
/// 3. Cancel the work item
/// 4. Work item's GetResult should throw WorkItemCancelException
/// </summary>
[Test]
[ExpectedException(typeof(WorkItemCancelException))]
public void CancelInQueueWorkItem()
{
STPStartInfo stpStartInfo = new STPStartInfo();
stpStartInfo.StartSuspended = true;
SmartThreadPool stp = new SmartThreadPool(stpStartInfo);
IWorkItemResult wir = stp.QueueWorkItem(delegate(object state) { return null; });
wir.Cancel();
Assert.IsTrue(wir.IsCanceled);
try
{
wir.GetResult();
}
finally
{
stp.Shutdown();
}
}
/// <summary>
/// 1. Create STP
/// 2. Queue work item that takes some time
/// 3. Wait for it to start
/// 4. Cancel the work item (soft)
/// 5. Work item's GetResult should throw WorkItemCancelException
/// </summary>
[Test]
[ExpectedException(typeof(WorkItemCancelException))]
public void CancelInProgressWorkItemSoft()
{
ManualResetEvent waitToStart = new ManualResetEvent(false);
SmartThreadPool stp = new SmartThreadPool();
IWorkItemResult wir = stp.QueueWorkItem(
delegate(object state) { waitToStart.Set(); Thread.Sleep(100); return null; }
);
waitToStart.WaitOne();
wir.Cancel(false);
Assert.IsTrue(wir.IsCanceled);
try
{
wir.GetResult();
}
finally
{
stp.Shutdown();
}
}
/// <summary>
/// 1. Create STP
/// 2. Queue work item that:
/// a. Sleep for 0.1 seconds
/// b. Increment the counter
/// 3. Wait for the work item to start
/// 4. Cancel the work item (abort)
/// 5. Make sure the work item result indicates the work item has been cancelled.
/// 6. Make sure the counter incrementation didn't happen
/// 7. Work item's GetResult should throw WorkItemCancelException
/// </summary>
[Test]
[ExpectedException(typeof(WorkItemCancelException))]
public void CancelInProgressWorkItemAbort()
{
ManualResetEvent waitToStart = new ManualResetEvent(false);
int counter = 0;
SmartThreadPool stp = new SmartThreadPool();
IWorkItemResult wir = stp.QueueWorkItem(
delegate(object state) { waitToStart.Set() ; Thread.Sleep(100); ++counter; return null; }
);
waitToStart.WaitOne();
wir.Cancel(true);
Assert.IsTrue(wir.IsCanceled);
Assert.AreEqual(counter, 0);
try
{
wir.GetResult();
}
finally
{
stp.Shutdown();
}
}
/// <summary>
/// 1. Create STP
/// 2. Queue work item that takes some time
/// 3. Wait for it to start
/// 4. Cancel the work item (soft)
/// 5. Make sure, in the work item, that SmartThreadPool.IsWorkItemCanceled is true
/// 5. Wait for the STP to get idle
/// 6. Work item's GetResult should throw WorkItemCancelException
/// </summary>
[Test]
public void CancelInProgressWorkItemSoftWithSample()
{
bool cancelled = false;
ManualResetEvent waitToStart = new ManualResetEvent(false);
ManualResetEvent waitToComplete = new ManualResetEvent(false);
SmartThreadPool stp = new SmartThreadPool();
IWorkItemResult wir = stp.QueueWorkItem(
delegate(object state) {
waitToStart.Set();
Thread.Sleep(100);
cancelled = SmartThreadPool.IsWorkItemCanceled;
waitToComplete.Set();
return null;
}
);
waitToStart.WaitOne();
wir.Cancel(false);
waitToComplete.WaitOne();
Assert.IsTrue(cancelled);
stp.Shutdown();
}
/// <summary>
/// 1. Create STP in suspended mode
/// 2. Queue work item into the STP
/// 3. Cancel the work item
/// 4. Start the STP
/// 5. Wait for the STP to get idle
/// 6. Work item's GetResult should throw WorkItemCancelException
/// 7. Cancel the work item again
/// 8. Work item's GetResult should throw WorkItemCancelException
/// </summary>
[Test]
[ExpectedException(typeof(WorkItemCancelException))]
public void CancelCanceledWorkItem()
{
STPStartInfo stpStartInfo = new STPStartInfo();
stpStartInfo.StartSuspended = true;
SmartThreadPool stp = new SmartThreadPool(stpStartInfo);
IWorkItemResult wir = stp.QueueWorkItem(delegate(object state) { return null; });
int counter = 0;
wir.Cancel();
try
{
wir.GetResult();
}
catch (WorkItemCancelException ce)
{
ce.GetHashCode();
++counter;
}
Assert.AreEqual(counter, 1);
wir.Cancel();
try
{
wir.GetResult();
}
finally
{
stp.Shutdown();
}
}
/// <summary>
/// 1. Create STP
/// 2. Queue work item into the STP
/// 3. Wait for the STP to get idle
/// 4. Work item's GetResult should return value
/// 4. Cancel the work item
/// 5. Work item's GetResult should return value
/// </summary>
[Test]
public void CancelCompletedWorkItem()
{
SmartThreadPool stp = new SmartThreadPool();
IWorkItemResult wir = stp.QueueWorkItem(
delegate(object state) { return 1; }
);
stp.WaitForIdle();
Assert.AreEqual(wir.GetResult(), 1);
wir.Cancel();
Assert.AreEqual(wir.GetResult(), 1);
stp.Shutdown();
}
/// <summary>
/// 1. Zero counter
/// 2. Create STP
/// 3. Queue 10 work items, that sleep and then increment the counter, into the STP
/// 4. Cancel the STP
/// 5. Make sure the counter is still zero
/// </summary>
[Test]
public void CancelSTPWorkItems()
{
// I don't use lock on the counter, since any number above 0 is a failure.
// In the worst case counter will be equal to 1 which is still not 0.
int counter = 0;
SmartThreadPool stp = new SmartThreadPool();
for (int i = 0; i < 10; i++)
{
stp.QueueWorkItem(
delegate(object state) { Thread.Sleep(500); ++counter; return null; }
);
}
Thread.Sleep(100);
stp.Cancel(true);
Assert.AreEqual(counter, 0);
stp.Shutdown();
}
/// <summary>
/// 1. Zero counter
/// 2. Create STP
/// 3. Create a WIG
/// 4. Queue 10 work items, that sleep and then increment the counter, into the WIG
/// 5. Cancel the WIG
/// 6. Wait for the WIG to become idle
/// 7. Make sure the counter is still zero
/// </summary>
[Test]
public void CancelWIGWorkItems()
{
// I don't use lock on the counter, since any number above 0 is a failure.
// In the worst case counter will be equal to 1 which is still not 0.
int counter = 0;
SmartThreadPool stp = new SmartThreadPool();
IWorkItemsGroup wig = stp.CreateWorkItemsGroup(10);
for (int i = 0; i < 10; i++)
{
wig.QueueWorkItem(
delegate(object state) { Thread.Sleep(500); ++counter; return null; }
);
}
Thread.Sleep(100);
wig.Cancel(true);
Assert.AreEqual(counter, 0);
stp.Shutdown();
}
/// <summary>
/// 1. Zero global counter
/// 2. Create STP
/// 3. Create a WIG1 in suspended mode
/// 4. Create a WIG2 in suspended mode
/// 5. Queue 5 work items, that increment the global counter, into the WIG1
/// 6. Queue 7 work items, that increment the global counter, into the WIG2
/// 7. Cancel the WIG1
/// 8. Start the WIG1
/// 9. Start the WIG2
/// 10. Wait for the STP to get idle
/// 11. Make sure the global counter is 7
/// </summary>
[Test]
public void Cancel1WIGof2WorkItems()
{
int counter1 = 0;
int counter2 = 0;
SmartThreadPool stp = new SmartThreadPool();
IWorkItemsGroup wig1 = stp.CreateWorkItemsGroup(3);
IWorkItemsGroup wig2 = stp.CreateWorkItemsGroup(3);
for (int i = 0; i < 3; i++)
{
wig1.QueueWorkItem(
delegate(object state) { Interlocked.Increment(ref counter1); Thread.Sleep(500); Interlocked.Increment(ref counter1); return null; }
);
}
for (int i = 0; i < 3; i++)
{
wig2.QueueWorkItem(
delegate(object state) { Thread.Sleep(500); Interlocked.Increment(ref counter2); return null; }
);
}
while (counter1 < 3)
{
Thread.Sleep(1);
}
wig1.Cancel(true);
stp.WaitForIdle();
Assert.AreEqual(3, counter1, "Cancelled WIG1");
Assert.AreEqual(3, counter2, "Normal WIG2");
stp.Shutdown();
}
//////////////////////////////////////////////////////////////////////////////////////////////////
/*
private int _counter;
/// <summary>
/// Example of how to queue a work item and then cancel it while it is in the queue.
/// </summary>
[Test]
[ExpectedException(typeof(WorkItemCancelException))]
public void WorkItemCanceling()
{
// Create a SmartThreadPool with only one thread.
// It just to show how to use the work item canceling feature
SmartThreadPool smartThreadPool = new SmartThreadPool(10*1000, 1);
// Queue a work item that will occupy the thread in the pool
IWorkItemResult wir1 =
smartThreadPool.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
// Queue another work item that will wait for the first to complete
IWorkItemResult wir2 =
smartThreadPool.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
// Wait a while for the thread pool to start executing the first work item
Thread.Sleep(100);
try
{
// The first work item cannot be canceled since it is currently executing
if (!wir1.Cancel())
{
// Cancel the second work item while it still in the queue
if (wir2.Cancel())
{
// Retreiving result of a canceled work item throws WorkItemCancelException exception
wir2.GetResult();
}
}
}
finally
{
smartThreadPool.Shutdown();
}
}
/// <summary>
/// </summary>
[Test]
public void WorkItemCancelingAndInUseWorkerThreads()
{
SmartThreadPool smartThreadPool = new SmartThreadPool(10*1000, 10);
IWorkItemResult [] wirs = new IWorkItemResult[100];
for(int i = 0; i < 100; ++i)
{
wirs[i] = smartThreadPool.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
}
// Wait a while for the thread pool to start executing the first work item
Thread.Sleep(100);
for(int i = 0; i < 100; ++i)
{
wirs[i].Cancel();
}
smartThreadPool.WaitForIdle(2000);
int inUseThreads = smartThreadPool.InUseThreads;
smartThreadPool.Shutdown();
Assert.AreEqual(0, inUseThreads);
}
private object DoSomeWork(object state)
{
Thread.Sleep(1000);
return 1;
}
/// <summary>
/// Check within the work item if it was cancelled
/// </summary>
[Test]
public void SampleIfWorkItemCancelled()
{
_counter = 0;
STPStartInfo stpStartInfo = new STPStartInfo();
stpStartInfo.StartSuspended = true;
// Create a SmartThreadPool with only one thread.
SmartThreadPool smartThreadPool = new SmartThreadPool(stpStartInfo);
IWorkItemResult[] wirs = new IWorkItemResult[100];
for (int i = 0; i < 100; ++i)
{
wirs[i] = smartThreadPool.QueueWorkItem(new WorkItemCallback(this.DoCheckForCancelledWorkItem), null);
}
for (int i = 0; i < 50; ++i)
{
wirs[i].Cancel();
}
smartThreadPool.Start();
smartThreadPool.WaitForIdle();
smartThreadPool.Shutdown();
Assert.AreEqual(50, _counter);
}
/// <summary>
/// 1. Create STP
/// 2. Queue work item into the STP
/// 4. Cancel the work item
/// 5. Work item doesn't check for cancel
/// 6. Work item quits
/// 7. Make sure the work item result is ok, and not an exception
/// </summary>
[Test]
public void TestWorkItemCancelledWorkItemOK()
{
// Create a SmartThreadPool with only one thread.
SmartThreadPool smartThreadPool = new SmartThreadPool();
AutoResetEvent start = new AutoResetEvent(false);
// Queue the work item
IWorkItemResult wir = smartThreadPool.QueueWorkItem(new WorkItemCallback(this.DoWaitForCancel), start);
// Wait for it to start executing
bool success = start.WaitOne(3000, false);
// Make sure it was started
Assert.IsTrue(success);
// Cancel the work item
wir.Cancel();
// Let it complete
start.Set();
// Wait for the work item to complete
smartThreadPool.WaitForIdle();
// Check the work item's result
// The work item started running after it was start its execution.
// Since the work item didn't sample the cancel, it was not aware that it
// was canceled. Therefore the result should be what the work item returned
// and not the cancel exeception
int result = (int)wir.GetResult(0, false);
smartThreadPool.Shutdown();
Assert.AreEqual(1, result);
}
/// <summary>
/// 1. Create STP
/// 2. Create WIG
/// 3. Queue work item into the WIG
/// 4. Cancel the work items in the WIG
/// 5. Work item doesn't check for cancel
/// 6. Work item quits
/// 7. Make sure the work item result is ok, and not an exception
/// </summary>
[Test]
public void TestWIGCancelledWorkItemOK()
{
// Create a SmartThreadPool with only one thread.
SmartThreadPool smartThreadPool = new SmartThreadPool();
IWorkItemsGroup wig = smartThreadPool.CreateWorkItemsGroup(1);
AutoResetEvent start = new AutoResetEvent(false);
// Queue the work item
IWorkItemResult wir = wig.QueueWorkItem(new WorkItemCallback(this.DoWaitForCancel), start);
// Wait for it to start executing
bool success = start.WaitOne(3000, false);
// Make sure it was started
Assert.IsTrue(success);
// Cancel the work item
wig.Cancel();
// Let it complete
start.Set();
// Wait for the work item to complete
smartThreadPool.WaitForIdle();
// Check the work item's result
// The work item started running after it was start its execution.
// Since the work item didn't sample the cancel, it was not aware that it
// was canceled. Therefore the result should be what the work item returned
// and not the cancel exeception
int result = (int)wir.GetResult(0, false);
smartThreadPool.Shutdown();
Assert.AreEqual(1, result);
}
/// <summary>
/// 1. Create STP
/// 2. Queue work item into the STP
/// 3. Cancel the work items in the STP
/// 4. Work item doesn't check for cancel
/// 5. Work item quits
/// 6. Make sure the work item result is ok, and not an exception
/// </summary>
[Test]
public void TestSTPCancelledWorkItemOK()
{
// Create a SmartThreadPool with only one thread.
SmartThreadPool smartThreadPool = new SmartThreadPool();
AutoResetEvent start = new AutoResetEvent(false);
// Queue the work item
IWorkItemResult wir = smartThreadPool.QueueWorkItem(new WorkItemCallback(this.DoWaitForCancel), start);
// Wait for it to start executing
bool success = start.WaitOne(3000, false);
// Make sure it was started
Assert.IsTrue(success);
// Cancel the work item
smartThreadPool.Cancel();
// Let it complete
start.Set();
// Wait for the work item to complete
smartThreadPool.WaitForIdle();
// Check the work item's result
// The work item started running after it was start its execution.
// Since the work item didn't sample the cancel, it was not aware that it
// was canceled. Therefore the result should be what the work item returned
// and not the cancel exeception
int result = (int)wir.GetResult(0, false);
smartThreadPool.Shutdown();
Assert.AreEqual(1, result);
}
/// <summary>
/// 1. Create STP
/// 2. Queue work item
/// 3. Cancel the work item
/// 4. Work item checks the cancel and quits
/// 5. Make sure the work item result throws exception
/// </summary>
[Test]
[ExpectedException(typeof(WorkItemCancelException))]
public void TestWorkItemCanceledWorkItemCancelException()
{
// Create a SmartThreadPool with only one thread.
SmartThreadPool smartThreadPool = new SmartThreadPool();
AutoResetEvent start = new AutoResetEvent(false);
// Queue the work item
IWorkItemResult wir = smartThreadPool.QueueWorkItem(new WorkItemCallback(this.DoCheckForCancel), start);
// Wait for it to start executing
bool success = start.WaitOne(3000, false);
// Make sure it was started
Assert.IsTrue(success);
// Cancel the work item
wir.Cancel();
// Let it complete
start.Set();
// Wait for the work item to complete
smartThreadPool.WaitForIdle();
try
{
// Check the work item's result
// The work item started running after it was start its execution.
// The work item samples the cancel, therefore it is aware that it
// was canceled. Using the GetResult should throw the cancel exeception
wir.GetResult(0, false);
}
finally
{
smartThreadPool.Shutdown();
}
}
/// <summary>
/// 1. Create STP
/// 2. Create WIG
/// 3. Queue work item into the WIG
/// 4. Cancel the work items in the WIG
/// 5. Work item checks the cancel and quits
/// 6. Make sure the work item result throws exception
/// </summary>
[Test]
[ExpectedException(typeof(WorkItemCancelException))]
public void TestWIGCancelledWorkItemCancelException()
{
// Create a SmartThreadPool with only one thread.
SmartThreadPool smartThreadPool = new SmartThreadPool();
IWorkItemsGroup wig = smartThreadPool.CreateWorkItemsGroup(1);
AutoResetEvent start = new AutoResetEvent(false);
// Queue the work item
IWorkItemResult wir = wig.QueueWorkItem(new WorkItemCallback(this.DoCheckForCancel), start);
// Wait for it to start executing
bool success = start.WaitOne(3000, false);
// Make sure it was started
Assert.IsTrue(success);
// Cancel the work item
wig.Cancel();
// Let it complete
start.Set();
// Wait for the work item to complete
smartThreadPool.WaitForIdle();
try
{
// Check the work item's result
// The work item started running after it was start its execution.
// The work item samples the cancel, therefore it is aware that it
// was canceled. Using the GetResult should throw the cancel exeception
wir.GetResult(0, false);
}
finally
{
smartThreadPool.Shutdown();
}
}
/// <summary>
/// 1. Create STP
/// 3. Queue work item into the STP
/// 4. Cancel the work items in the STP
/// 5. Work item checks the cancel and quits
/// 6. Make sure the work item result throws exception
/// </summary>
[Test]
[ExpectedException(typeof(WorkItemCancelException))]
public void TestSTPCancelledWorkItemCancelException()
{
// Create a SmartThreadPool with only one thread.
SmartThreadPool smartThreadPool = new SmartThreadPool();
AutoResetEvent start = new AutoResetEvent(false);
// Queue the work item
IWorkItemResult wir = smartThreadPool.QueueWorkItem(new WorkItemCallback(this.DoCheckForCancel), start);
// Wait for it to start executing
bool success = start.WaitOne(3000, false);
// Make sure it was started
Assert.IsTrue(success);
// Cancel the work item
smartThreadPool.Cancel();
// Let it complete
start.Set();
// Wait for the work item to complete
smartThreadPool.WaitForIdle();
try
{
// Check the work item's result
// The work item started running after it was start its execution.
// The work item samples the cancel, therefore it is aware that it
// was canceled. Using the GetResult should throw the cancel exeception
wir.GetResult(0, false);
}
finally
{
smartThreadPool.Shutdown();
}
}
private object DoCheckForCancelledWorkItem(object state)
{
if (!SmartThreadPool.IsWorkItemCanceled)
{
Interlocked.Increment(ref _counter);
}
return null;
}
private object DoWaitForCancel(object state)
{
AutoResetEvent start = state as AutoResetEvent;
// Signal the test that the work item started
start.Set();
// Let the test run (or else the next line may reset the signaled event)
Thread.Sleep(10);
// Wait for the test to cancel the work item
start.WaitOne();
return 1;
}
private object DoCheckForCancel(object state)
{
AutoResetEvent start = state as AutoResetEvent;
// Signal the test that the work item started
start.Set();
// Let the test run (or else the next line may reset the signaled event)
Thread.Sleep(10);
// Wait for the test to cancel the work item
start.WaitOne();
// Sample if the work item was cancelled
bool cancelled = SmartThreadPool.IsWorkItemCanceled;
return 1;
}
*/
}
}
+156
View File
@@ -0,0 +1,156 @@
using System;
using System.Threading;
using System.Diagnostics;
using NUnit.Framework;
using Amib.Threading;
namespace SmartThreadPoolTests
{
/// <summary>
/// Summary description for TestConcurrencyChanges.
/// </summary>
[TestFixture]
[Category("TestConcurrencyChanges")]
public class TestConcurrencyChanges
{
public TestConcurrencyChanges()
{
}
/// <summary>
/// Example of waiting for idle
/// </summary>
[Test]
public void TestMaxThreadsChange()
{
SmartThreadPool smartThreadPool = new SmartThreadPool(1 * 1000, 1, 0);
bool success = false;
for (int i = 0; i < 100; ++i)
{
smartThreadPool.QueueWorkItem(
new WorkItemCallback(this.DoSomeWork),
null);
}
success = WaitForMaxThreadsValue(smartThreadPool, 1, 1 * 1000);
Assert.IsTrue(success);
smartThreadPool.MaxThreads = 5;
success = WaitForMaxThreadsValue(smartThreadPool, 5, 2 * 1000);
Assert.IsTrue(success);
smartThreadPool.MaxThreads = 25;
success = WaitForMaxThreadsValue(smartThreadPool, 25, 4 * 1000);
Assert.IsTrue(success);
smartThreadPool.MaxThreads = 10;
success = WaitForMaxThreadsValue(smartThreadPool, 10, 10 * 1000);
Assert.IsTrue(success);
smartThreadPool.Shutdown();
}
[Test]
public void TestMinThreadsChange()
{
SmartThreadPool smartThreadPool = new SmartThreadPool(1 * 1000, 25, 0);
bool success = false;
success = WaitForMinThreadsValue(smartThreadPool, 0, 1 * 1000);
Assert.IsTrue(success);
smartThreadPool.MinThreads = 5;
success = WaitForMinThreadsValue(smartThreadPool, 5, 2 * 1000);
Assert.IsTrue(success);
smartThreadPool.MinThreads = 25;
success = WaitForMinThreadsValue(smartThreadPool, 25, 4 * 1000);
Assert.IsTrue(success);
smartThreadPool.MinThreads = 10;
success = WaitForMinThreadsValue(smartThreadPool, 10, 10 * 1000);
Assert.IsTrue(success);
smartThreadPool.Shutdown();
}
/// <summary>
/// Example of waiting for idle
/// </summary>
[Test]
public void TestConcurrencyChange()
{
SmartThreadPool smartThreadPool = new SmartThreadPool(10 * 1000, 1, 0);
bool success = false;
for (int i = 0; i < 100; ++i)
{
smartThreadPool.QueueWorkItem(
new WorkItemCallback(this.DoSomeWork),
null);
}
smartThreadPool.Concurrency = 1;
success = WaitForMaxThreadsValue(smartThreadPool, 1, 1 * 1000);
Assert.IsTrue(success);
smartThreadPool.Concurrency = 5;
success = WaitForMaxThreadsValue(smartThreadPool, 5, 2 * 1000);
Assert.IsTrue(success);
smartThreadPool.Concurrency = 25;
success = WaitForMaxThreadsValue(smartThreadPool, 25, 4 * 1000);
Assert.IsTrue(success);
smartThreadPool.Concurrency = 10;
success = WaitForMaxThreadsValue(smartThreadPool, 10, 10 * 1000);
Assert.IsTrue(success);
smartThreadPool.Shutdown();
}
private bool WaitForMaxThreadsValue(SmartThreadPool smartThreadPool, int maxThreadsCount, int timeout)
{
DateTime end = DateTime.Now + new TimeSpan(0, 0, 0, 0, timeout);
bool success = false;
while(DateTime.Now <= end && !success)
{
success = (smartThreadPool.InUseThreads == maxThreadsCount);
Thread.Sleep(10);
}
return success;
}
private bool WaitForMinThreadsValue(SmartThreadPool smartThreadPool, int minThreadsCount, int timeout)
{
DateTime end = DateTime.Now + new TimeSpan(0, 0, 0, 0, timeout);
bool success = false;
while (DateTime.Now <= end && !success)
{
success = (smartThreadPool.ActiveThreads == minThreadsCount);
Thread.Sleep(10);
}
return success;
}
private int x = 0;
private object DoSomeWork(object state)
{
Debug.WriteLine(Interlocked.Increment(ref x));
Thread.Sleep(1000);
return 1;
}
}
}
+246
View File
@@ -0,0 +1,246 @@
using System;
using Amib.Threading;
using NUnit.Framework;
using System.Net;
namespace STPTests
{
/// <summary>
/// Summary description for TestFalseFillStateWithArgs.
/// </summary>
[TestFixture]
[Category("TestFalseFillStateWithArgs")]
public class TestFalseFillStateWithArgs
{
private SmartThreadPool _stp;
private IWorkItemsGroup _wig;
[SetUp]
public void Init()
{
_stp = new SmartThreadPool();
_wig = _stp.CreateWorkItemsGroup(10);
}
[TearDown]
public void Fini()
{
_stp.WaitForIdle();
_stp.Shutdown();
}
[Test]
public void STPActionT0()
{
IWorkItemResult wir = _stp.QueueWorkItem(Action0);
Assert.IsNull(wir.State);
}
[Test]
public void STPActionT1()
{
IWorkItemResult wir = _stp.QueueWorkItem(Action1, 17);
Assert.IsNull(wir.State);
}
[Test]
public void STPActionT2()
{
IWorkItemResult wir = _stp.QueueWorkItem(Action2, 'a', "bla bla");
Assert.IsNull(wir.State);
}
[Test]
public void STPActionT3()
{
char[] chars = new char[] { 'a', 'b' };
object obj = new object();
IWorkItemResult wir = _stp.QueueWorkItem(Action3, true, chars, obj);
Assert.IsNull(wir.State);
}
[Test]
public void STPActionT4()
{
IntPtr p = new IntPtr(int.MaxValue);
Guid guid = Guid.NewGuid();
IPAddress ip = IPAddress.Parse("1.2.3.4");
IWorkItemResult wir = _stp.QueueWorkItem(Action4, long.MinValue, p, ip, guid);
Assert.IsNull(wir.State);
}
[Test]
public void STPFuncT0()
{
IWorkItemResult<int> wir = _stp.QueueWorkItem(new Func<int>(Func0));
Assert.IsNull(wir.State);
}
[Test]
public void STPFuncT1()
{
IWorkItemResult<bool> wir = _stp.QueueWorkItem(new Func<int, bool>(Func1), 17);
Assert.IsNull(wir.State);
}
[Test]
public void STPFuncT2()
{
IWorkItemResult<string> wir = _stp.QueueWorkItem(new Func<char, string, string>(Func2), 'a', "bla bla");
Assert.IsNull(wir.State);
}
[Test]
public void STPFuncT3()
{
char[] chars = new char[] { 'a', 'b' };
object obj = new object();
IWorkItemResult<char> wir = _stp.QueueWorkItem(new Func<bool, char[], object, char>(Func3), true, chars, obj);
Assert.IsNull(wir.State);
}
[Test]
public void STPFuncT4()
{
IntPtr p = new IntPtr(int.MaxValue);
Guid guid = Guid.NewGuid();
IPAddress ip = IPAddress.Parse("1.2.3.4");
IWorkItemResult<IPAddress> wir = _stp.QueueWorkItem(new Func<long, IntPtr, IPAddress, Guid, IPAddress>(Func4), long.MinValue, p, ip, guid);
Assert.IsNull(wir.State);
}
[Test]
public void WIGActionT0()
{
IWorkItemResult wir = _wig.QueueWorkItem(Action0);
Assert.IsNull(wir.State);
}
[Test]
public void WIGActionT1()
{
IWorkItemResult wir = _wig.QueueWorkItem(Action1, 17);
Assert.IsNull(wir.State);
}
[Test]
public void WIGActionT2()
{
IWorkItemResult wir = _wig.QueueWorkItem(Action2, 'a', "bla bla");
Assert.IsNull(wir.State);
}
[Test]
public void WIGActionT3()
{
char[] chars = new char[] { 'a', 'b' };
object obj = new object();
IWorkItemResult wir = _wig.QueueWorkItem(Action3, true, chars, obj);
Assert.IsNull(wir.State);
}
[Test]
public void WIGActionT4()
{
IntPtr p = new IntPtr(int.MaxValue);
Guid guid = Guid.NewGuid();
IPAddress ip = IPAddress.Parse("1.2.3.4");
IWorkItemResult wir = _wig.QueueWorkItem(Action4, long.MinValue, p, ip, guid);
Assert.IsNull(wir.State);
}
[Test]
public void WIGFuncT0()
{
IWorkItemResult<int> wir = _wig.QueueWorkItem(new Func<int>(Func0));
Assert.IsNull(wir.State);
}
[Test]
public void WIGFuncT1()
{
IWorkItemResult<bool> wir = _wig.QueueWorkItem(new Func<int, bool>(Func1), 17);
Assert.IsNull(wir.State);
}
[Test]
public void WIGFuncT2()
{
IWorkItemResult<string> wir = _wig.QueueWorkItem(new Func<char, string, string>(Func2), 'a', "bla bla");
Assert.IsNull(wir.State);
}
[Test]
public void WIGFuncT3()
{
char[] chars = new char[] { 'a', 'b' };
object obj = new object();
IWorkItemResult<char> wir = _wig.QueueWorkItem(new Func<bool, char[], object, char>(Func3), true, chars, obj);
Assert.IsNull(wir.State);
}
[Test]
public void WIGFuncT4()
{
IntPtr p = new IntPtr(int.MaxValue);
Guid guid = Guid.NewGuid();
IPAddress ip = IPAddress.Parse("1.2.3.4");
IWorkItemResult<IPAddress> wir = _wig.QueueWorkItem(new Func<long, IntPtr, IPAddress, Guid, IPAddress>(Func4), long.MinValue, p, ip, guid);
Assert.IsNull(wir.State);
}
private void Action0()
{
}
private void Action1(int p1)
{
}
private void Action2(char p1, string p2)
{
}
private void Action3(bool p1, char[] p2, object p3)
{
}
private void Action4(long p1, IntPtr p2, IPAddress p3, Guid p4)
{
}
private int Func0()
{
return 0;
}
private bool Func1(int p1)
{
return true;
}
private string Func2(char p1, string p2)
{
return "value";
}
private char Func3(bool p1, char[] p2, object p3)
{
return 'z';
}
private IPAddress Func4(long p1, IntPtr p2, IPAddress p3, Guid p4)
{
return IPAddress.None;
}
}
}
+207
View File
@@ -0,0 +1,207 @@
using System;
using Amib.Threading;
using NUnit.Framework;
using System.Net;
namespace STPTests
{
/// <summary>
/// Summary description for TestFillStateWithArgs.
/// </summary>
[TestFixture]
[Category("TestFillStateWithArgs")]
public class TestFillStateWithArgs
{
private SmartThreadPool _stp;
[SetUp]
public void Init()
{
STPStartInfo stpStartInfo = new STPStartInfo();
stpStartInfo.FillStateWithArgs = true;
_stp = new SmartThreadPool(stpStartInfo);
}
[TearDown]
public void Fini()
{
_stp.WaitForIdle();
_stp.Shutdown();
}
[Test]
public void ActionT0()
{
IWorkItemResult wir = _stp.QueueWorkItem(Action0);
Assert.IsNull(wir.State);
}
[Test]
public void ActionT1()
{
IWorkItemResult wir = _stp.QueueWorkItem(Action1, 17);
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 1);
Assert.AreEqual(args[0], 17);
}
[Test]
public void ActionT2()
{
IWorkItemResult wir = _stp.QueueWorkItem(Action2, 'a', "bla bla");
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 2);
Assert.AreEqual(args[0], 'a');
Assert.AreEqual(args[1], "bla bla");
}
[Test]
public void ActionT3()
{
char[] chars = new char[] {'a', 'b'};
object obj = new object();
IWorkItemResult wir = _stp.QueueWorkItem(Action3, true, chars, obj);
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 3);
Assert.AreEqual(args[0], true);
Assert.AreEqual(args[1], chars);
Assert.AreEqual(args[2], obj);
}
[Test]
public void ActionT4()
{
IntPtr p = new IntPtr(int.MaxValue);
Guid guid = Guid.NewGuid();
IPAddress ip = IPAddress.Parse("1.2.3.4");
IWorkItemResult wir = _stp.QueueWorkItem(Action4, long.MinValue, p, ip, guid);
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 4);
Assert.AreEqual(args[0], long.MinValue);
Assert.AreEqual(args[1], p);
Assert.AreEqual(args[2], ip);
Assert.AreEqual(args[3], guid);
}
[Test]
public void FuncT0()
{
IWorkItemResult<int> wir = _stp.QueueWorkItem(new Func<int>(Func0));
Assert.AreEqual(wir.State, null);
}
[Test]
public void FuncT1()
{
IWorkItemResult<bool> wir = _stp.QueueWorkItem(new Func<int, bool>(Func1), 17);
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 1);
Assert.AreEqual(args[0], 17);
}
[Test]
public void FuncT2()
{
IWorkItemResult<string> wir = _stp.QueueWorkItem(new Func<char, string, string>(Func2), 'a', "bla bla");
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 2);
Assert.AreEqual(args[0], 'a');
Assert.AreEqual(args[1], "bla bla");
}
[Test]
public void FuncT3()
{
char[] chars = new char[] { 'a', 'b' };
object obj = new object();
IWorkItemResult<char> wir = _stp.QueueWorkItem(new Func<bool, char[], object, char>(Func3), true, chars, obj);
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 3);
Assert.AreEqual(args[0], true);
Assert.AreEqual(args[1], chars);
Assert.AreEqual(args[2], obj);
}
[Test]
public void FuncT4()
{
IntPtr p = new IntPtr(int.MaxValue);
Guid guid = Guid.NewGuid();
IPAddress ip = IPAddress.Parse("1.2.3.4");
IWorkItemResult<IPAddress> wir = _stp.QueueWorkItem(new Func<long, IntPtr, IPAddress, Guid, IPAddress>(Func4), long.MinValue, p, ip, guid);
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 4);
Assert.AreEqual(args[0], long.MinValue);
Assert.AreEqual(args[1], p);
Assert.AreEqual(args[2], ip);
Assert.AreEqual(args[3], guid);
}
private void Action0()
{
}
private void Action1(int p1)
{
}
private void Action2(char p1, string p2)
{
}
private void Action3(bool p1, char [] p2, object p3)
{
}
private void Action4(long p1, IntPtr p2, IPAddress p3, Guid p4)
{
}
private int Func0()
{
return 0;
}
private bool Func1(int p1)
{
return true;
}
private string Func2(char p1, string p2)
{
return "value";
}
private char Func3(bool p1, char[] p2, object p3)
{
return 'z';
}
private IPAddress Func4(long p1, IntPtr p2, IPAddress p3, Guid p4)
{
return IPAddress.None;
}
}
}
+43
View File
@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Text;
using Amib.Threading;
using NUnit.Framework;
namespace STPTests
{
/// <summary>
/// Summary description for TestCancel.
/// </summary>
[TestFixture]
[Category("TestFuncT")]
public class TestFuncT
{
[Test]
public void FuncT()
{
SmartThreadPool stp = new SmartThreadPool();
IWorkItemResult<int> wir =
stp.QueueWorkItem(new Func<int, int>(f), 1);
int y = wir.GetResult();
Assert.AreEqual(y, 2);
try
{
wir.GetResult();
}
finally
{
stp.Shutdown();
}
}
private int f(int x)
{
return x + 1;
}
}
}
+112
View File
@@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
using System.Text;
using Amib.Threading;
using NUnit.Framework;
namespace SmartThreadPoolTests
{
/// <summary>
/// Summary description for TestCancel.
/// </summary>
[TestFixture]
[Category("TestFuncT")]
public class TestFuncT
{
private SmartThreadPool _stp;
[SetUp]
public void Init()
{
_stp = new SmartThreadPool();
}
[TearDown]
public void Fini()
{
_stp.Shutdown();
}
[Test]
public void FuncT0()
{
IWorkItemResult<int> wir = _stp.QueueWorkItem(new Func<int>(MaxInt));
int result = wir.GetResult();
Assert.AreEqual(result, int.MaxValue);
}
[Test]
public void FuncT1()
{
IWorkItemResult<bool> wir = _stp.QueueWorkItem(new Func<bool, bool>(Not), true);
bool result = wir.Result;
Assert.AreEqual(result, false);
}
[Test]
public void FuncT2()
{
IWorkItemResult<string> wir = _stp.QueueWorkItem(new Func<string, string, string>(string.Concat), "ABC", "xyz");
string result = wir.Result;
Assert.AreEqual(result, "ABCxyz");
}
[Test]
public void FuncT3()
{
IWorkItemResult<string> wir = _stp.QueueWorkItem(new Func<string, int, int, string>(Substring), "ABCDEF", 1, 2);
string result = wir.Result;
Assert.AreEqual(result, "BC");
}
[Test]
public void FuncT4()
{
int[] numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
IWorkItemResult<int[]> wir = _stp.QueueWorkItem(new Func<int[], int, int, int, int[]>(Subarray), numbers, 1, 2, 3);
int[] result = wir.Result;
Assert.AreEqual(result, new int[] { 2, 3, 2, 3, 2, 3, });
}
private int MaxInt()
{
return int.MaxValue;
}
private bool Not(bool flag)
{
return !flag;
}
private string Substring(string s, int startIndex, int length)
{
return s.Substring(startIndex, length);
}
private int[] Subarray(int[] numbers, int startIndex, int length, int repeat)
{
int[] result = new int[length * repeat];
for (int i = 0; i < repeat; i++)
{
for (int j = 0; j < length; j++)
{
result[i * length + j] = numbers[startIndex + j];
}
}
return result;
}
}
}
+43 -134
View File
@@ -42,144 +42,52 @@ namespace SmartThreadPoolTests
/// Example of how to queue a work item and then wait on a timeout for the result.
/// </summary>
[Test]
public void Timeout()
[ExpectedException(typeof(WorkItemTimeoutException))]
public void Timeout()
{
SmartThreadPool smartThreadPool = new SmartThreadPool();
bool success = false;
IWorkItemResult wir =
smartThreadPool.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
try
{
wir.GetResult(500, true);
}
catch (WorkItemTimeoutException)
{
success = true;
}
try
{
wir.GetResult(500, true);
}
finally
{
smartThreadPool.Shutdown();
}
}
smartThreadPool.Shutdown();
/// <summary>
/// Example of how to interrupt the waiting for a work item to complete.
/// </summary>
[Test]
[ExpectedException(typeof(WorkItemTimeoutException))]
public void WorkItemWaitCanceling()
{
SmartThreadPool smartThreadPool = new SmartThreadPool();
Assert.IsTrue(success);
}
ManualResetEvent cancelWaitHandle = new ManualResetEvent(false);
/// <summary>
/// Example of how to queue a work item and then cancel it while it is in the queue.
/// </summary>
[Test]
public void WorkItemCanceling()
{
// Create a SmartThreadPool with only one thread.
// It just to show how to use the work item canceling feature
SmartThreadPool smartThreadPool = new SmartThreadPool(10*1000, 1);
bool success = false;
// Queue a work item that will occupy the thread in the pool
IWorkItemResult wir1 =
smartThreadPool.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
// Queue another work item that will wait for the first to complete
IWorkItemResult wir2 =
smartThreadPool.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
// Wait a while for the thread pool to start executing the first work item
Thread.Sleep(100);
// The first work item cannot be canceled since it is currently executing
if (!wir1.Cancel())
{
// Cancel the second work item while it still in the queue
if (wir2.Cancel())
{
try
{
// Retreiving result of a canceled work item throws an exception
wir2.GetResult();
}
catch (WorkItemCancelException)
{
success = true;
}
}
}
smartThreadPool.Shutdown();
Assert.IsTrue(success);
}
/// <summary>
/// Example of how to interrupt the waiting for a work item to complete.
/// </summary>
[Test]
public void WorkItemWaitCanceling()
{
SmartThreadPool smartThreadPool = new SmartThreadPool();
ManualResetEvent cancelWaitHandle = new ManualResetEvent(false);
bool success = false;
// Queue a work item that will occupy the thread in the pool
IWorkItemResult wir1 =
smartThreadPool.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
// Queue another work item that will wait for the first to complete
IWorkItemResult wir2 =
smartThreadPool.QueueWorkItem(new WorkItemCallback(this.SignalCancel), cancelWaitHandle);
try
{
wir1.GetResult(System.Threading.Timeout.Infinite, true, cancelWaitHandle);
}
catch (WorkItemTimeoutException)
{
success = true;
}
smartThreadPool.Shutdown();
Assert.IsTrue(success);
}
/// <summary>
/// Example of how to queue a work item and then cancel it while it is in the queue.
/// </summary>
[Test]
public void WorkItemCancelingAndInUseWorkerThreads()
{
// Create a SmartThreadPool with only one thread.
// It just to show how to use the work item canceling feature
SmartThreadPool smartThreadPool = new SmartThreadPool(10*1000, 10);
IWorkItemResult [] wirs = new IWorkItemResult[100];
for(int i = 0; i < 100; ++i)
{
wirs[i] = smartThreadPool.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
}
// Wait a while for the thread pool to start executing the first work item
Thread.Sleep(100);
for(int i = 0; i < 100; ++i)
{
wirs[i].Cancel();
}
smartThreadPool.WaitForIdle(2000);
int inUseThreads = smartThreadPool.InUseThreads;
smartThreadPool.Shutdown();
Assert.AreEqual(0, inUseThreads);
}
// Queue a work item that will occupy the thread in the pool
IWorkItemResult wir1 =
smartThreadPool.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
// Queue another work item that will wait for the first to complete
IWorkItemResult wir2 =
smartThreadPool.QueueWorkItem(new WorkItemCallback(this.SignalCancel), cancelWaitHandle);
try
{
wir1.GetResult(System.Threading.Timeout.Infinite, true, cancelWaitHandle);
}
finally
{
smartThreadPool.Shutdown();
}
}
private object DoSomeWork(object state)
{
@@ -187,12 +95,13 @@ namespace SmartThreadPoolTests
return 1;
}
private object SignalCancel(object state)
{
ManualResetEvent cancelWaitHandle = state as ManualResetEvent;
Thread.Sleep(250);
cancelWaitHandle.Set();
return null;
}
private object SignalCancel(object state)
{
ManualResetEvent cancelWaitHandle = state as ManualResetEvent;
Thread.Sleep(250);
cancelWaitHandle.Set();
return null;
}
}
}
+68
View File
@@ -228,5 +228,73 @@ namespace SmartThreadPoolTests
Thread.Sleep(1000);
return 1;
}
[Test]
public void WaitAllT()
{
SmartThreadPool smartThreadPool = new SmartThreadPool();
bool success = true;
IWorkItemResult<int>[] wirs = new IWorkItemResult<int>[5];
for (int i = 0; i < wirs.Length; ++i)
{
wirs[i] = smartThreadPool.QueueWorkItem(new Func<int, int, int>(Math.Min), i, i + 1);
}
SmartThreadPool.WaitAll(wirs);
for (int i = 0; i < wirs.Length; ++i)
{
if (!wirs[i].IsCompleted)
{
success = false;
break;
}
int result = wirs[i].GetResult();
if (i != result)
{
success = false;
break;
}
}
smartThreadPool.Shutdown();
Assert.IsTrue(success);
}
[Test]
public void WaitAnyT()
{
SmartThreadPool smartThreadPool = new SmartThreadPool();
bool success = false;
IWorkItemResult<int>[] wirs = new IWorkItemResult<int>[5];
for (int i = 0; i < wirs.Length; ++i)
{
wirs[i] = smartThreadPool.QueueWorkItem(new Func<int, int, int>(Math.Max), i, i - 1);
}
int index = SmartThreadPool.WaitAny(wirs);
if (wirs[index].IsCompleted)
{
int result = wirs[index].GetResult();
if (index == result)
{
success = true;
}
}
smartThreadPool.Shutdown();
Assert.IsTrue(success);
}
}
}
+98
View File
@@ -0,0 +1,98 @@
using NUnit.Framework;
using Amib.Threading;
namespace SmartThreadPoolTests
{
/// <summary>
/// Tests for QueueWorkItem.
/// </summary>
[TestFixture]
[Category("TestQueueWorkItem")]
public class TestQueueWorkItem
{
private SmartThreadPool _stp;
[SetUp]
public void Init()
{
_stp = new SmartThreadPool();
}
[TearDown]
public void Fini()
{
_stp.Shutdown();
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback);
[Test]
public void TestQueueWorkItemCall()
{
QueueWorkItemHelper.TestQueueWorkItemCall(_stp);
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback, WorkItemPriority workItemPriority);
[Test]
public void TestQueueWorkItemCallPrio()
{
QueueWorkItemHelper.TestQueueWorkItemCallPrio(_stp);
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state);
[Test]
public void TestQueueWorkItemCallStat()
{
QueueWorkItemHelper.TestQueueWorkItemCallStat(_stp);
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, WorkItemPriority workItemPriority);
[Test]
public void TestQueueWorkItemCallStatPrio()
{
QueueWorkItemHelper.TestQueueWorkItemCallStatPrio(_stp);
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback);
[Test]
public void TestQueueWorkItemCallStatPost()
{
QueueWorkItemHelper.TestQueueWorkItemCallStatPost(_stp);
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, WorkItemPriority workItemPriority);
[Test]
public void TestQueueWorkItemCallStatPostPrio()
{
QueueWorkItemHelper.TestQueueWorkItemCallStatPostPrio(_stp);
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute);
[Test]
public void TestQueueWorkItemCallStatPostPflg()
{
QueueWorkItemHelper.TestQueueWorkItemCallStatPostPflg(_stp);
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute, WorkItemPriority workItemPriority);
[Test]
public void TestQueueWorkItemCallStatPostPflgPrio()
{
QueueWorkItemHelper.TestQueueWorkItemCallStatPostPflgPrio(_stp);
}
//IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback);
[Test]
public void TestQueueWorkItemInfoCall()
{
QueueWorkItemHelper.TestQueueWorkItemInfoCall(_stp);
}
//IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state);
[Test]
public void TestQueueWorkItemInfoCallStat()
{
QueueWorkItemHelper.TestQueueWorkItemInfoCallStat(_stp);
}
}
}
+99
View File
@@ -0,0 +1,99 @@
using System;
using System.Threading;
using NUnit.Framework;
using Amib.Threading;
namespace SmartThreadPoolTests
{
/// <summary>
/// </summary>
[TestFixture]
[Category("TestThreadsCreate")]
public class TestThreadsCreate
{
private bool _initSuccess;
private bool _workItemSuccess;
private bool _termSuccess;
private void ClearResults()
{
_initSuccess = false;
_workItemSuccess = false;
_termSuccess = false;
}
[Test]
public void TestThreadsEvents()
{
ClearResults();
SmartThreadPool stp = new SmartThreadPool();
stp.OnThreadInitialization += new ThreadInitializationHandler(OnInitialization);
stp.OnThreadTermination += new ThreadTerminationHandler(OnTermination);
stp.QueueWorkItem(new WorkItemCallback(DoSomeWork), null);
stp.WaitForIdle();
stp.Shutdown();
Assert.IsTrue(_initSuccess);
Assert.IsTrue(_workItemSuccess);
Assert.IsTrue(_termSuccess);
}
public void OnInitialization()
{
ThreadContextState.Current.Counter = 1234;
_initSuccess = true;
}
private object DoSomeWork(object state)
{
int counter = ThreadContextState.Current.Counter;
_workItemSuccess = (1234 == counter);
ThreadContextState.Current.Counter = 1111;
return 1;
}
public void OnTermination()
{
int counter = ThreadContextState.Current.Counter;
_termSuccess = (1111 == counter);
}
}
internal class ThreadContextState
{
// Each thread will have its own ThreadContextState object
[ThreadStatic]
private static ThreadContextState _threadContextState;
private int _counter = 0;
public int Counter
{
get { return _counter; }
set { _counter = value; }
}
// Static member so it can be used anywhere in code of the work item method
public static ThreadContextState Current
{
get
{
// If the _threadContextState is null then it was not yet initialized
// for this thread.
if (null == _threadContextState)
{
// Create a ThreadContextState object
_threadContextState = new ThreadContextState();
}
return _threadContextState;
}
}
}
}
+126
View File
@@ -0,0 +1,126 @@
using Amib.Threading;
using NUnit.Framework;
namespace WorkItemsGroupTests
{
/// <summary>
/// Summary description for TestCancel.
/// </summary>
[TestFixture]
[Category("TestWIGActionT")]
public class TestWIGActionT
{
private SmartThreadPool _stp;
private IWorkItemsGroup _wig;
private object _result;
[SetUp]
public void Init()
{
_stp = new SmartThreadPool();
_wig = _stp.CreateWorkItemsGroup(10);
}
[TearDown]
public void Fini()
{
_stp.Shutdown();
}
[Test]
public void ActionT0()
{
_result = null;
IWorkItemResult wir = _wig.QueueWorkItem(MaxInt);
wir.GetResult();
Assert.AreEqual(_result, int.MaxValue);
}
[Test]
public void ActionT1()
{
_result = null;
IWorkItemResult wir = _wig.QueueWorkItem(Not, true);
wir.GetResult();
Assert.AreEqual(_result, false);
}
[Test]
public void ActionT2()
{
_result = null;
IWorkItemResult wir = _wig.QueueWorkItem(Concat, "ABC", "xyz");
wir.GetResult();
Assert.AreEqual(_result, "ABCxyz");
}
[Test]
public void ActionT3()
{
_result = null;
IWorkItemResult wir = _wig.QueueWorkItem(Substring, "ABCDEF", 1, 2);
wir.GetResult();
Assert.AreEqual(_result, "BC");
}
[Test]
public void ActionT4()
{
_result = null;
int[] numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
IWorkItemResult wir = _wig.QueueWorkItem(Subarray, numbers, 1, 2, 3);
wir.GetResult();
Assert.AreEqual(_result, new int[] { 2, 3, 2, 3, 2, 3, });
}
private void MaxInt()
{
_result = int.MaxValue;
}
private void Not(bool flag)
{
_result = !flag;
}
private void Concat(string s1, string s2)
{
_result = s1 + s2;
}
private void Substring(string s, int startIndex, int length)
{
_result = s.Substring(startIndex, length);
}
private void Subarray(int[] numbers, int startIndex, int length, int repeat)
{
int[] result = new int[length * repeat];
for (int i = 0; i < repeat; i++)
{
for (int j = 0; j < length; j++)
{
result[i * length + j] = numbers[startIndex + j];
}
}
_result = result;
}
}
}
+1 -1
View File
@@ -5,7 +5,7 @@ using NUnit.Framework;
using Amib.Threading;
namespace SmartThreadPoolTests
namespace WorkItemsGroupTests
{
/// <summary>
/// Summary description for TestWIGConcurrency.
+213
View File
@@ -0,0 +1,213 @@
using System;
using System.Threading;
using System.Diagnostics;
using NUnit.Framework;
using Amib.Threading;
namespace WorkItemsGroupTests
{
/// <summary>
/// Summary description for TestWIGConcurrencyChanges.
/// </summary>
[TestFixture]
[Category("TestWIGConcurrencyChanges")]
public class TestWIGConcurrencyChanges
{
public TestWIGConcurrencyChanges()
{
}
/// <summary>
/// Example of waiting for idle
/// </summary>
[Test]
public void TestWIGConcurrencyChange1WIG()
{
SmartThreadPool smartThreadPool = new SmartThreadPool(10*1000, 1, 0);
Assert.IsTrue(0 == smartThreadPool.WaitingCallbacks);
PauseSTP(smartThreadPool);
Thread.Sleep(100);
Assert.IsTrue(0 == smartThreadPool.WaitingCallbacks);
IWorkItemsGroup wig = smartThreadPool.CreateWorkItemsGroup(1);
wig.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
Assert.IsTrue(1 == smartThreadPool.WaitingCallbacks);
wig.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
Assert.IsTrue(1 == smartThreadPool.WaitingCallbacks);
wig.Concurrency = 2;
Thread.Sleep(100);
Assert.IsTrue(2 == smartThreadPool.WaitingCallbacks);
ResumeSTP(smartThreadPool);
Thread.Sleep(100);
Assert.IsTrue(0 == smartThreadPool.WaitingCallbacks);
PauseSTP(smartThreadPool);
wig.Concurrency = 1;
wig.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
Assert.IsTrue(1 == smartThreadPool.WaitingCallbacks);
wig.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
Assert.IsTrue(1 == smartThreadPool.WaitingCallbacks);
ResumeSTP(smartThreadPool);
Thread.Sleep(100);
Assert.IsTrue(0 == smartThreadPool.WaitingCallbacks);
smartThreadPool.Shutdown();
}
/// <summary>
/// Example of waiting for idle
/// </summary>
[Test]
public void TestWIGConcurrencyChange2WIGs()
{
SmartThreadPool smartThreadPool = new SmartThreadPool(10 * 1000, 2, 0);
Assert.IsTrue(0 == smartThreadPool.WaitingCallbacks);
PauseSTP(smartThreadPool);
PauseSTP(smartThreadPool);
Thread.Sleep(100);
Assert.IsTrue(0 == smartThreadPool.WaitingCallbacks);
IWorkItemsGroup wig1 = smartThreadPool.CreateWorkItemsGroup(1);
IWorkItemsGroup wig2 = smartThreadPool.CreateWorkItemsGroup(1);
wig1.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
Assert.IsTrue(1 == smartThreadPool.WaitingCallbacks);
wig2.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
Assert.IsTrue(2 == smartThreadPool.WaitingCallbacks);
wig1.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
Assert.IsTrue(2 == smartThreadPool.WaitingCallbacks);
wig2.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
Assert.IsTrue(2 == smartThreadPool.WaitingCallbacks);
wig1.Concurrency = 2;
Thread.Sleep(100);
Assert.IsTrue(3 == smartThreadPool.WaitingCallbacks);
wig2.Concurrency = 2;
Thread.Sleep(100);
Assert.IsTrue(4 == smartThreadPool.WaitingCallbacks);
ResumeSTP(smartThreadPool);
Thread.Sleep(100);
Assert.IsTrue(0 == smartThreadPool.WaitingCallbacks);
PauseSTP(smartThreadPool);
PauseSTP(smartThreadPool);
Thread.Sleep(100);
wig1.Concurrency = 1;
wig1.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
Assert.IsTrue(1 == smartThreadPool.WaitingCallbacks);
wig2.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
Assert.IsTrue(2 == smartThreadPool.WaitingCallbacks);
ResumeSTP(smartThreadPool);
Thread.Sleep(100);
Assert.IsTrue(0 == smartThreadPool.WaitingCallbacks);
smartThreadPool.Shutdown();
}
private void PauseSTP(SmartThreadPool stp)
{
_pauseSTP.Reset();
stp.QueueWorkItem(
new WorkItemCallback(this.DoPauseSTP),
null);
}
private void ResumeSTP(SmartThreadPool stp)
{
_pauseSTP.Set();
}
private ManualResetEvent _pauseSTP = new ManualResetEvent(false);
private object DoPauseSTP(object state)
{
_pauseSTP.WaitOne();
return 1;
}
private object DoSomeWork(object state)
{
return 1;
}
/*
/// <summary>
/// Example of waiting for idle
/// </summary>
[Test]
public void WaitForIdle()
{
SmartThreadPool smartThreadPool = new SmartThreadPool(10*1000, 25, 0);
bool success = false;
for(int i = 0; i < 100; ++i)
{
smartThreadPool.QueueWorkItem(
new WorkItemCallback(this.DoSomeWork),
null);
}
success = !smartThreadPool.WaitForIdle(3500);
success = success && smartThreadPool.WaitForIdle(1000);
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;
}
*/
}
}
+210
View File
@@ -0,0 +1,210 @@
using System;
using Amib.Threading;
using NUnit.Framework;
using System.Net;
namespace STPTests
{
/// <summary>
/// Summary description for TestWIGFillStateWithArgs.
/// </summary>
[TestFixture]
[Category("TestWIGFillStateWithArgs")]
public class TestWIGFillStateWithArgs
{
private SmartThreadPool _stp;
private IWorkItemsGroup _wig;
[SetUp]
public void Init()
{
_stp = new SmartThreadPool();
WIGStartInfo wigStartInfo = new WIGStartInfo();
wigStartInfo.FillStateWithArgs = true;
_wig = _stp.CreateWorkItemsGroup(10, wigStartInfo);
}
[TearDown]
public void Fini()
{
_stp.WaitForIdle();
_stp.Shutdown();
}
[Test]
public void ActionT0()
{
IWorkItemResult wir = _wig.QueueWorkItem(Action0);
Assert.IsNull(wir.State);
}
[Test]
public void ActionT1()
{
IWorkItemResult wir = _wig.QueueWorkItem(Action1, 17);
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 1);
Assert.AreEqual(args[0], 17);
}
[Test]
public void ActionT2()
{
IWorkItemResult wir = _wig.QueueWorkItem(Action2, 'a', "bla bla");
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 2);
Assert.AreEqual(args[0], 'a');
Assert.AreEqual(args[1], "bla bla");
}
[Test]
public void ActionT3()
{
char[] chars = new char[] { 'a', 'b' };
object obj = new object();
IWorkItemResult wir = _wig.QueueWorkItem(Action3, true, chars, obj);
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 3);
Assert.AreEqual(args[0], true);
Assert.AreEqual(args[1], chars);
Assert.AreEqual(args[2], obj);
}
[Test]
public void ActionT4()
{
IntPtr p = new IntPtr(int.MaxValue);
Guid guid = Guid.NewGuid();
IPAddress ip = IPAddress.Parse("1.2.3.4");
IWorkItemResult wir = _wig.QueueWorkItem(Action4, long.MinValue, p, ip, guid);
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 4);
Assert.AreEqual(args[0], long.MinValue);
Assert.AreEqual(args[1], p);
Assert.AreEqual(args[2], ip);
Assert.AreEqual(args[3], guid);
}
[Test]
public void FuncT0()
{
IWorkItemResult<int> wir = _wig.QueueWorkItem(new Func<int>(Func0));
Assert.AreEqual(wir.State, null);
}
[Test]
public void FuncT1()
{
IWorkItemResult<bool> wir = _wig.QueueWorkItem(new Func<int, bool>(Func1), 17);
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 1);
Assert.AreEqual(args[0], 17);
}
[Test]
public void FuncT2()
{
IWorkItemResult<string> wir = _wig.QueueWorkItem(new Func<char, string, string>(Func2), 'a', "bla bla");
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 2);
Assert.AreEqual(args[0], 'a');
Assert.AreEqual(args[1], "bla bla");
}
[Test]
public void FuncT3()
{
char[] chars = new char[] { 'a', 'b' };
object obj = new object();
IWorkItemResult<char> wir = _wig.QueueWorkItem(new Func<bool, char[], object, char>(Func3), true, chars, obj);
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 3);
Assert.AreEqual(args[0], true);
Assert.AreEqual(args[1], chars);
Assert.AreEqual(args[2], obj);
}
[Test]
public void FuncT4()
{
IntPtr p = new IntPtr(int.MaxValue);
Guid guid = Guid.NewGuid();
IPAddress ip = IPAddress.Parse("1.2.3.4");
IWorkItemResult<IPAddress> wir = _wig.QueueWorkItem(new Func<long, IntPtr, IPAddress, Guid, IPAddress>(Func4), long.MinValue, p, ip, guid);
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 4);
Assert.AreEqual(args[0], long.MinValue);
Assert.AreEqual(args[1], p);
Assert.AreEqual(args[2], ip);
Assert.AreEqual(args[3], guid);
}
private void Action0()
{
}
private void Action1(int p1)
{
}
private void Action2(char p1, string p2)
{
}
private void Action3(bool p1, char[] p2, object p3)
{
}
private void Action4(long p1, IntPtr p2, IPAddress p3, Guid p4)
{
}
private int Func0()
{
return 0;
}
private bool Func1(int p1)
{
return true;
}
private string Func2(char p1, string p2)
{
return "value";
}
private char Func3(bool p1, char[] p2, object p3)
{
return 'z';
}
private IPAddress Func4(long p1, IntPtr p2, IPAddress p3, Guid p4)
{
return IPAddress.None;
}
}
}
+207
View File
@@ -0,0 +1,207 @@
using System;
using Amib.Threading;
using NUnit.Framework;
using System.Net;
namespace STPTests
{
/// <summary>
/// Summary description for TestFillStateWithParams.
/// </summary>
[TestFixture]
[Category("TestFillStateWithParams")]
public class TestFillStateWithParams
{
private SmartThreadPool _stp;
[SetUp]
public void Init()
{
STPStartInfo stpStartInfo = new STPStartInfo();
stpStartInfo.FillStateWithParams = true;
_stp = new SmartThreadPool(stpStartInfo);
}
[TearDown]
public void Fini()
{
_stp.WaitForIdle();
_stp.Shutdown();
}
[Test]
public void ActionT0()
{
IWorkItemResult wir = _stp.QueueWorkItem(Action0);
Assert.IsNull(wir.State);
}
[Test]
public void ActionT1()
{
IWorkItemResult wir = _stp.QueueWorkItem(Action1, 17);
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 1);
Assert.AreEqual(args[0], 17);
}
[Test]
public void ActionT2()
{
IWorkItemResult wir = _stp.QueueWorkItem(Action2, 'a', "bla bla");
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 2);
Assert.AreEqual(args[0], 'a');
Assert.AreEqual(args[1], "bla bla");
}
[Test]
public void ActionT3()
{
char[] chars = new char[] {'a', 'b'};
object obj = new object();
IWorkItemResult wir = _stp.QueueWorkItem(Action3, true, chars, obj);
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 3);
Assert.AreEqual(args[0], true);
Assert.AreEqual(args[1], chars);
Assert.AreEqual(args[2], obj);
}
[Test]
public void ActionT4()
{
IntPtr p = new IntPtr(int.MaxValue);
Guid guid = Guid.NewGuid();
IPAddress ip = IPAddress.Parse("1.2.3.4");
IWorkItemResult wir = _stp.QueueWorkItem(Action4, long.MinValue, p, ip, guid);
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 4);
Assert.AreEqual(args[0], long.MinValue);
Assert.AreEqual(args[1], p);
Assert.AreEqual(args[2], ip);
Assert.AreEqual(args[3], guid);
}
[Test]
public void FuncT0()
{
IWorkItemResult<int> wir = _stp.QueueWorkItem(new Func<int>(Func0));
Assert.AreEqual(wir.State, null);
}
[Test]
public void FuncT1()
{
IWorkItemResult<bool> wir = _stp.QueueWorkItem(new Func<int, bool>(Func1), 17);
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 1);
Assert.AreEqual(args[0], 17);
}
[Test]
public void FuncT2()
{
IWorkItemResult<string> wir = _stp.QueueWorkItem(new Func<char, string, string>(Func2), 'a', "bla bla");
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 2);
Assert.AreEqual(args[0], 'a');
Assert.AreEqual(args[1], "bla bla");
}
[Test]
public void FuncT3()
{
char[] chars = new char[] { 'a', 'b' };
object obj = new object();
IWorkItemResult<char> wir = _stp.QueueWorkItem(new Func<bool, char[], object, char>(Func3), true, chars, obj);
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 3);
Assert.AreEqual(args[0], true);
Assert.AreEqual(args[1], chars);
Assert.AreEqual(args[2], obj);
}
[Test]
public void FuncT4()
{
IntPtr p = new IntPtr(int.MaxValue);
Guid guid = Guid.NewGuid();
IPAddress ip = IPAddress.Parse("1.2.3.4");
IWorkItemResult<IPAddress> wir = _stp.QueueWorkItem(new Func<long, IntPtr, IPAddress, Guid, IPAddress>(Func4), long.MinValue, p, ip, guid);
object[] args = wir.State as object[];
Assert.IsNotNull(args);
Assert.AreEqual(args.Length, 4);
Assert.AreEqual(args[0], long.MinValue);
Assert.AreEqual(args[1], p);
Assert.AreEqual(args[2], ip);
Assert.AreEqual(args[3], guid);
}
private void Action0()
{
}
private void Action1(int p1)
{
}
private void Action2(char p1, string p2)
{
}
private void Action3(bool p1, char [] p2, object p3)
{
}
private void Action4(long p1, IntPtr p2, IPAddress p3, Guid p4)
{
}
private int Func0()
{
return 0;
}
private bool Func1(int p1)
{
return true;
}
private string Func2(char p1, string p2)
{
return "value";
}
private char Func3(bool p1, char[] p2, object p3)
{
return 'z';
}
private IPAddress Func4(long p1, IntPtr p2, IPAddress p3, Guid p4)
{
return IPAddress.None;
}
}
}
+107
View File
@@ -0,0 +1,107 @@
using Amib.Threading;
using NUnit.Framework;
namespace WorkItemsGroupTests
{
[TestFixture]
[Category("TestWIGFuncT")]
public class TestWIGFuncT
{
private SmartThreadPool _stp;
private IWorkItemsGroup _wig;
[SetUp]
public void Init()
{
_stp = new SmartThreadPool();
_wig = _stp.CreateWorkItemsGroup(10);
}
[TearDown]
public void Fini()
{
_stp.Shutdown();
}
[Test]
public void FuncT0()
{
IWorkItemResult<int> wir = _wig.QueueWorkItem(new Func<int>(MaxInt));
int result = wir.GetResult();
Assert.AreEqual(result, int.MaxValue);
}
[Test]
public void FuncT1()
{
IWorkItemResult<bool> wir = _wig.QueueWorkItem(new Func<bool, bool>(Not), true);
bool result = wir.Result;
Assert.AreEqual(result, false);
}
[Test]
public void FuncT2()
{
IWorkItemResult<string> wir = _wig.QueueWorkItem(new Func<string, string, string>(string.Concat), "ABC", "xyz");
string result = wir.Result;
Assert.AreEqual(result, "ABCxyz");
}
[Test]
public void FuncT3()
{
IWorkItemResult<string> wir = _wig.QueueWorkItem(new Func<string, int, int, string>(Substring), "ABCDEF", 1, 2);
string result = wir.Result;
Assert.AreEqual(result, "BC");
}
[Test]
public void FuncT4()
{
int[] numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
IWorkItemResult<int[]> wir = _wig.QueueWorkItem(new Func<int[], int, int, int, int[]>(Subarray), numbers, 1, 2, 3);
int[] result = wir.Result;
Assert.AreEqual(result, new int[] { 2, 3, 2, 3, 2, 3, });
}
private int MaxInt()
{
return int.MaxValue;
}
private bool Not(bool flag)
{
return !flag;
}
private string Substring(string s, int startIndex, int length)
{
return s.Substring(startIndex, length);
}
private int[] Subarray(int[] numbers, int startIndex, int length, int repeat)
{
int[] result = new int[length * repeat];
for (int i = 0; i < repeat; i++)
{
for (int j = 0; j < length; j++)
{
result[i * length + j] = numbers[startIndex + j];
}
}
return result;
}
}
}
-47
View File
@@ -67,53 +67,6 @@ namespace WorkItemsGroupTests
Assert.IsTrue(success);
}
/// <summary>
/// Example of how to queue a work item and then cancel it while it is in the queue.
/// </summary>
[Test]
public void WorkItemCanceling()
{
// Create a SmartThreadPool with only one thread.
// It just to show how to use the work item canceling feature
SmartThreadPool smartThreadPool = new SmartThreadPool(10*1000, 1);
IWorkItemsGroup workItemsGroup = smartThreadPool.CreateWorkItemsGroup(int.MaxValue);
bool success = false;
// Queue a work item that will occupy the thread in the pool
IWorkItemResult wir1 =
workItemsGroup.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
// Queue another work item that will wait for the first to complete
IWorkItemResult wir2 =
workItemsGroup.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
// Wait a while for the thread pool to start executing the first work item
Thread.Sleep(100);
// The first work item cannot be canceled since it is currently executing
if (!wir1.Cancel())
{
// Cancel the second work item while it still in the queue
if (wir2.Cancel())
{
try
{
// Retreiving result of a canceled work item throws an exception
wir2.GetResult();
}
catch (WorkItemCancelException)
{
success = true;
}
}
}
smartThreadPool.Shutdown();
Assert.IsTrue(success);
}
/// <summary>
/// Example of how to interrupt the waiting for a work item to complete.
/// </summary>
+104
View File
@@ -0,0 +1,104 @@
using System;
using System.Threading;
using NUnit.Framework;
using Amib.Threading;
using SmartThreadPoolTests;
namespace WorkItemsGroupTests
{
/// <summary>
/// Tests for QueueWorkItem.
/// </summary>
[TestFixture]
[Category("TestQueueWorkItem")]
public class TestQueueWorkItem
{
private SmartThreadPool _stp;
private IWorkItemsGroup _wig;
[SetUp]
public void Init()
{
_stp = new SmartThreadPool();
_wig = _stp.CreateWorkItemsGroup(SmartThreadPool.DefaultMaxWorkerThreads);
}
[TearDown]
public void Fini()
{
_stp.Shutdown();
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback);
[Test]
public void TestQueueWorkItemCall()
{
QueueWorkItemHelper.TestQueueWorkItemCall(_wig);
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback, WorkItemPriority workItemPriority);
[Test]
public void TestQueueWorkItemCallPrio()
{
QueueWorkItemHelper.TestQueueWorkItemCallPrio(_wig);
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state);
[Test]
public void TestQueueWorkItemCallStat()
{
QueueWorkItemHelper.TestQueueWorkItemCallStat(_wig);
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, WorkItemPriority workItemPriority);
[Test]
public void TestQueueWorkItemCallStatPrio()
{
QueueWorkItemHelper.TestQueueWorkItemCallStatPrio(_wig);
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback);
[Test]
public void TestQueueWorkItemCallStatPost()
{
QueueWorkItemHelper.TestQueueWorkItemCallStatPost(_wig);
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, WorkItemPriority workItemPriority);
[Test]
public void TestQueueWorkItemCallStatPostPrio()
{
QueueWorkItemHelper.TestQueueWorkItemCallStatPostPrio(_wig);
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute);
[Test]
public void TestQueueWorkItemCallStatPostPflg()
{
QueueWorkItemHelper.TestQueueWorkItemCallStatPostPflg(_wig);
}
//IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute, WorkItemPriority workItemPriority);
[Test]
public void TestQueueWorkItemCallStatPostPflgPrio()
{
QueueWorkItemHelper.TestQueueWorkItemCallStatPostPflgPrio(_wig);
}
//IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback);
[Test]
public void TestQueueWorkItemInfoCall()
{
QueueWorkItemHelper.TestQueueWorkItemInfoCall(_wig);
}
//IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state);
[Test]
public void TestQueueWorkItemInfoCallStat()
{
QueueWorkItemHelper.TestQueueWorkItemInfoCallStat(_wig);
}
}
}
+66 -12
View File
@@ -29,15 +29,17 @@ namespace WorkItemsGroupTests
IWorkItemsGroup workItemsGroup = smartThreadPool.CreateWorkItemsGroup(int.MaxValue);
bool success = false;
ManualResetEvent isRunning = new ManualResetEvent(false);
for(int i = 0; i < 100; ++i)
for (int i = 0; i < 4; ++i)
{
workItemsGroup.QueueWorkItem(
new WorkItemCallback(this.DoSomeWork),
null);
workItemsGroup.QueueWorkItem(delegate { isRunning.WaitOne(); });
}
success = !workItemsGroup.WaitForIdle(3500);
success = !workItemsGroup.WaitForIdle(1000);
isRunning.Set();
success = success && workItemsGroup.WaitForIdle(1000);
smartThreadPool.Shutdown();
@@ -61,7 +63,7 @@ namespace WorkItemsGroupTests
smartThreadPool.Shutdown();
Assert.IsNotNull(e);
}
}
[Test]
public void WaitForIdleOnSTPThreadForAnotherWorkItemsGroup()
@@ -72,11 +74,11 @@ namespace WorkItemsGroupTests
workItemsGroup1.QueueWorkItem(
new WorkItemCallback(this.DoSomeWork),
null);
1000);
workItemsGroup1.QueueWorkItem(
new WorkItemCallback(this.DoSomeWork),
null);
1000);
IWorkItemResult wir = workItemsGroup2.QueueWorkItem(
new WorkItemCallback(this.DoWaitForIdle),
@@ -91,11 +93,16 @@ namespace WorkItemsGroupTests
}
private int x = 0;
private int _x = 0;
private object DoSomeWork(object state)
{
Debug.WriteLine(Interlocked.Increment(ref x));
Thread.Sleep(1000);
{
int sleepTime = (int)state;
int newX = Interlocked.Increment(ref _x);
Console.WriteLine("{0}: Enter, newX = {1}", DateTime.Now.ToLongTimeString(), newX);
Console.WriteLine("{0}: Sleeping for {1} ms", DateTime.Now.ToLongTimeString(), sleepTime);
Thread.Sleep(sleepTime);
newX = Interlocked.Increment(ref _x);
Console.WriteLine("{0}: Leave, newX = {1}", DateTime.Now.ToLongTimeString(), newX);
return 1;
}
@@ -105,5 +112,52 @@ namespace WorkItemsGroupTests
workItemsGroup.WaitForIdle();
return null;
}
[Test]
public void WaitForIdleWithCancel()
{
SmartThreadPool smartThreadPool = new SmartThreadPool(10 * 1000, 1, 1);
IWorkItemsGroup workItemsGroup = smartThreadPool.CreateWorkItemsGroup(2);
_x = 0;
IWorkItemResult wir1 = workItemsGroup.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), 1000);
IWorkItemResult wir2 = workItemsGroup.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), 1000);
IWorkItemResult wir3 = workItemsGroup.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), 1000);
while (0 == _x)
{
Thread.Sleep(10);
}
Console.WriteLine("{0}: Cancelling WIG", DateTime.Now.ToLongTimeString());
workItemsGroup.Cancel();
// At this point:
// The first work item is running
// The second work item is cancelled, but waits in the STP queue
// The third work item is cancelled.
Assert.AreEqual(1, _x);
Assert.IsTrue(wir2.IsCanceled);
Assert.IsTrue(wir3.IsCanceled);
// Make sure the workItemsGroup is still idle
Assert.IsFalse(workItemsGroup.IsIdle);
Console.WriteLine("{0}: Waiting for 1st result", DateTime.Now.ToLongTimeString());
wir1.GetResult();
Assert.AreEqual(2, _x);
bool isIdle = workItemsGroup.WaitForIdle(100);
Assert.IsTrue(isIdle);
smartThreadPool.Shutdown();
}
}
}
+7 -5
View File
@@ -28,15 +28,17 @@ namespace SmartThreadPoolTests
SmartThreadPool smartThreadPool = new SmartThreadPool(10*1000, 25, 0);
bool success = false;
ManualResetEvent isRunning = new ManualResetEvent(false);
for(int i = 0; i < 100; ++i)
for(int i = 0; i < 4; ++i)
{
smartThreadPool.QueueWorkItem(
new WorkItemCallback(this.DoSomeWork),
null);
smartThreadPool.QueueWorkItem(delegate { isRunning.WaitOne(); });
}
success = !smartThreadPool.WaitForIdle(3500);
success = !smartThreadPool.WaitForIdle(1000);
isRunning.Set();
success = success && smartThreadPool.WaitForIdle(1000);
smartThreadPool.Shutdown();
-47
View File
@@ -70,53 +70,6 @@ namespace WorkItemsGroupTests
Assert.IsTrue(success);
}
/// <summary>
/// Example of how to queue a work item and then cancel it while it is in the queue.
/// </summary>
[Test]
public void WorkItemCanceling()
{
// Create a SmartThreadPool with only one thread.
// It just to show how to use the work item canceling feature
SmartThreadPool smartThreadPool = new SmartThreadPool(10*1000, 1);
IWorkItemsGroup workItemsGroup = smartThreadPool.CreateWorkItemsGroup(int.MaxValue);
bool success = false;
// Queue a work item that will occupy the thread in the pool
IWorkItemResult wir1 =
workItemsGroup.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
// Queue another work item that will wait for the first to complete
IWorkItemResult wir2 =
workItemsGroup.QueueWorkItem(new WorkItemCallback(this.DoSomeWork), null);
// Wait a while for the thread pool to start executing the first work item
Thread.Sleep(100);
// The first work item cannot be canceled since it is currently executing
if (!wir1.Cancel())
{
// Cancel the second work item while it still in the queue
if (wir2.Cancel())
{
try
{
// Retreiving result of a canceled work item throws an exception
wir2.GetResult();
}
catch (WorkItemCancelException)
{
success = true;
}
}
}
smartThreadPool.Shutdown();
Assert.IsTrue(success);
}
/// <summary>
/// Example of how to interrupt the waiting for a work item to complete.
/// </summary>