mirror of
https://github.com/farcasclaudiu/SmartThreadPool.git
synced 2026-06-28 07:00:59 +03:00
v2.0
SmartThreadPool v2.0
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ using NUnit.Framework;
|
||||
|
||||
using Amib.Threading;
|
||||
|
||||
namespace SmartThreadPoolTests
|
||||
namespace WorkItemsGroupTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for TestWIGConcurrency.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user