Added refactorings suggested by Simon Cropp

This commit is contained in:
Ami Bar
2009-12-19 17:33:30 +02:00
parent 1bd7e4d104
commit d2c14da5ad
62 changed files with 785 additions and 1131 deletions
+7 -12
View File
@@ -1,11 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics; using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using Amib.Threading; using Amib.Threading;
using System.Threading; using System.Threading;
@@ -26,11 +21,11 @@ namespace STPCEDemo
uiTimer = new System.Windows.Forms.Timer(); uiTimer = new System.Windows.Forms.Timer();
uiTimer.Interval = 1000; uiTimer.Interval = 1000;
uiTimer.Tick += new EventHandler(uiTimer_Tick); uiTimer.Tick += uiTimer_Tick;
wiTimer = new System.Windows.Forms.Timer(); wiTimer = new System.Windows.Forms.Timer();
wiTimer.Interval = 1000; wiTimer.Interval = 1000;
wiTimer.Tick += new EventHandler(wiTimer_Tick); wiTimer.Tick += wiTimer_Tick;
//Debug.WriteLine("Form Thread Priority is " + (int)GetCurrentThreadPriority()); //Debug.WriteLine("Form Thread Priority is " + (int)GetCurrentThreadPriority());
} }
@@ -50,11 +45,11 @@ namespace STPCEDemo
int inUse = _stp.InUseThreads; int inUse = _stp.InUseThreads;
int inPool = _stp.ActiveThreads; int inPool = _stp.ActiveThreads;
this.usageHistoryControl1.AddValues(inUse, inPool); usageHistoryControl1.AddValues(inUse, inPool);
this.usageControl1.Value1 = inUse; usageControl1.Value1 = inUse;
this.usageControl1.Value2 = inPool; usageControl1.Value2 = inPool;
this.lblThreadsInUse.Text = inUse.ToString(); lblThreadsInUse.Text = inUse.ToString();
this.lblThreadsInPool.Text = inPool.ToString(); lblThreadsInPool.Text = inPool.ToString();
} }
catch(Exception ex) catch(Exception ex)
{ {
-3
View File
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Text;
namespace STPCEDemo namespace STPCEDemo
{ {
-1
View File
@@ -1,5 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Windows.Forms; using System.Windows.Forms;
namespace STPCEDemo namespace STPCEDemo
-1
View File
@@ -1,5 +1,4 @@
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following
+12 -16
View File
@@ -1,9 +1,5 @@
using System; using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;
using System.Windows.Forms; using System.Windows.Forms;
using STPCEDemo; using STPCEDemo;
@@ -12,7 +8,7 @@ namespace UsageControl
/// <summary> /// <summary>
/// Summary description for UsageControl. /// Summary description for UsageControl.
/// </summary> /// </summary>
public class UsageControl : System.Windows.Forms.UserControl public class UsageControl : UserControl
{ {
private System.ComponentModel.IContainer components = null; private System.ComponentModel.IContainer components = null;
@@ -83,7 +79,7 @@ namespace UsageControl
Width = fixedWidth; Width = fixedWidth;
rows = (ClientRectangle.Height / 4) - 1; rows = (ClientRectangle.Height / 4) - 1;
// Invalidate the control to get a repaint. // Invalidate the control to get a repaint.
this.Invalidate(); Invalidate();
} }
protected override void OnPaint(PaintEventArgs e) protected override void OnPaint(PaintEventArgs e)
@@ -99,7 +95,7 @@ namespace UsageControl
int emptyCount = rows - Math.Max(filledCount1, filledCount2); int emptyCount = rows - Math.Max(filledCount1, filledCount2);
int i = 0; int i;
for(i = 0; i < filledCount1; ++i) for(i = 0; i < filledCount1; ++i)
{ {
@@ -176,7 +172,7 @@ namespace UsageControl
} }
// Invalidate the control to get a repaint. // Invalidate the control to get a repaint.
this.Invalidate(); Invalidate();
} }
} }
@@ -310,17 +306,17 @@ namespace UsageControl
int PenWidth = (int)Pens.White.Width; int PenWidth = (int)Pens.White.Width;
g.DrawLine(Pens.DarkGray, g.DrawLine(Pens.DarkGray,
this.ClientRectangle.Left, this.ClientRectangle.Top, ClientRectangle.Left, ClientRectangle.Top,
this.ClientRectangle.Width - PenWidth, this.ClientRectangle.Top); ClientRectangle.Width - PenWidth, ClientRectangle.Top);
g.DrawLine(Pens.DarkGray, g.DrawLine(Pens.DarkGray,
this.ClientRectangle.Left, this.ClientRectangle.Top, ClientRectangle.Left, ClientRectangle.Top,
this.ClientRectangle.Left, this.ClientRectangle.Height - PenWidth); ClientRectangle.Left, ClientRectangle.Height - PenWidth);
g.DrawLine(Pens.White, g.DrawLine(Pens.White,
this.ClientRectangle.Left, this.ClientRectangle.Height - PenWidth, ClientRectangle.Left, ClientRectangle.Height - PenWidth,
this.ClientRectangle.Width - PenWidth, this.ClientRectangle.Height - PenWidth); ClientRectangle.Width - PenWidth, ClientRectangle.Height - PenWidth);
g.DrawLine(Pens.White, g.DrawLine(Pens.White,
this.ClientRectangle.Width - PenWidth, this.ClientRectangle.Top, ClientRectangle.Width - PenWidth, ClientRectangle.Top,
this.ClientRectangle.Width - PenWidth, this.ClientRectangle.Height - PenWidth); ClientRectangle.Width - PenWidth, ClientRectangle.Height - PenWidth);
} }
+3 -6
View File
@@ -1,8 +1,5 @@
using System; using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.Data;
using System.Windows.Forms; using System.Windows.Forms;
using STPCEDemo; using STPCEDemo;
@@ -11,7 +8,7 @@ namespace UsageControl
/// <summary> /// <summary>
/// Summary description for UsageHistoryControl. /// Summary description for UsageHistoryControl.
/// </summary> /// </summary>
public class UsageHistoryControl : System.Windows.Forms.UserControl public class UsageHistoryControl : UserControl
{ {
/// <summary> /// <summary>
/// Required designer variable. /// Required designer variable.
@@ -94,7 +91,7 @@ namespace UsageControl
protected override void OnResize(EventArgs e) protected override void OnResize(EventArgs e)
{ {
// Invalidate the control to get a repaint. // Invalidate the control to get a repaint.
this.Invalidate(); Invalidate();
} }
protected override void OnPaint(PaintEventArgs e) protected override void OnPaint(PaintEventArgs e)
@@ -184,7 +181,7 @@ namespace UsageControl
max = value; max = value;
// Invalidate the control to get a repaint. // Invalidate the control to get a repaint.
this.Invalidate(); Invalidate();
} }
} }
-44
View File
@@ -1,11 +1,5 @@
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly: AssemblyTitle("")] [assembly: AssemblyTitle("")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
@@ -14,45 +8,7 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyCopyright("")] [assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.*")]
//
// In order to sign your assembly you must specify a key to use. Refer to the
// Microsoft .NET Framework documentation for more information on assembly signing.
//
// Use the attributes below to control which key is used for signing.
//
// Notes:
// (*) If no key is specified, the assembly is not signed.
// (*) KeyName refers to a key that has been installed in the Crypto Service
// Provider (CSP) on your machine. KeyFile refers to a file which contains
// a key.
// (*) If the KeyFile and the KeyName values are both specified, the
// following processing occurs:
// (1) If the KeyName can be found in the CSP, that key is used.
// (2) If the KeyName does not exist and the KeyFile does exist, the key
// in the KeyFile is installed into the CSP and used.
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
// When specifying the KeyFile, the location of the KeyFile should be
// relative to the project output directory which is
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
// located in the project directory, you would specify the AssemblyKeyFile
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
// documentation for more information on this.
//
[assembly: AssemblyDelaySign(false)] [assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")] [assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")] [assembly: AssemblyKeyName("")]
+1 -1
View File
@@ -23,7 +23,7 @@ namespace Examples
smartThreadPool.QueueWorkItem(new smartThreadPool.QueueWorkItem(new
WorkItemCallback(this.DoDiv), divArgs); WorkItemCallback(this.DoDiv), divArgs);
Exception e = null; Exception e;
object obj = wir.GetResult(out e); object obj = wir.GetResult(out e);
// e contains the expetion that DoDiv threw // e contains the expetion that DoDiv threw
if(null == e) if(null == e)
+2 -1
View File
@@ -1,3 +1,4 @@
using System;
using System.Diagnostics; using System.Diagnostics;
using Amib.Threading; using Amib.Threading;
@@ -11,7 +12,7 @@ namespace Examples
IWorkItemsGroup wig = smartThreadPool.CreateWorkItemsGroup(1); IWorkItemsGroup wig = smartThreadPool.CreateWorkItemsGroup(1);
wig.OnIdle += new WorkItemsGroupIdleHandler(wig_OnIdle); wig.OnIdle += wig_OnIdle;
foreach(object state in states) foreach(object state in states)
{ {
+1
View File
@@ -1,3 +1,4 @@
using System;
using System.Diagnostics; using System.Diagnostics;
using Amib.Threading; using Amib.Threading;
+2 -4
View File
@@ -1,6 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Text;
using Amib.Threading; using Amib.Threading;
namespace STPExamples namespace STPExamples
@@ -26,8 +24,8 @@ namespace STPExamples
{ {
SmartThreadPool stp = new SmartThreadPool(); SmartThreadPool stp = new SmartThreadPool();
stp.OnThreadInitialization += new ThreadInitializationHandler(OnInitialization); stp.OnThreadInitialization += OnInitialization;
stp.OnThreadTermination += new ThreadTerminationHandler(OnTermination); stp.OnThreadTermination += OnTermination;
stp.QueueWorkItem(DoSomeWork); stp.QueueWorkItem(DoSomeWork);
} }
+1
View File
@@ -1,3 +1,4 @@
using System;
using Amib.Threading; using Amib.Threading;
namespace Examples namespace Examples
+1
View File
@@ -1,3 +1,4 @@
using System;
using System.Threading; using System.Threading;
using Amib.Threading; using Amib.Threading;
+1
View File
@@ -1,3 +1,4 @@
using System;
using Amib.Threading; using Amib.Threading;
namespace Examples namespace Examples
-44
View File
@@ -1,11 +1,5 @@
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly: AssemblyTitle("")] [assembly: AssemblyTitle("")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
@@ -14,45 +8,7 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyCopyright("")] [assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.*")]
//
// In order to sign your assembly you must specify a key to use. Refer to the
// Microsoft .NET Framework documentation for more information on assembly signing.
//
// Use the attributes below to control which key is used for signing.
//
// Notes:
// (*) If no key is specified, the assembly is not signed.
// (*) KeyName refers to a key that has been installed in the Crypto Service
// Provider (CSP) on your machine. KeyFile refers to a file which contains
// a key.
// (*) If the KeyFile and the KeyName values are both specified, the
// following processing occurs:
// (1) If the KeyName can be found in the CSP, that key is used.
// (2) If the KeyName does not exist and the KeyFile does exist, the key
// in the KeyFile is installed into the CSP and used.
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
// When specifying the KeyFile, the location of the KeyFile should be
// relative to the project output directory which is
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
// located in the project directory, you would specify the AssemblyKeyFile
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
// documentation for more information on this.
//
[assembly: AssemblyDelaySign(false)] [assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")] [assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")] [assembly: AssemblyKeyName("")]
-3
View File
@@ -1,9 +1,6 @@
using System; using System;
using System.Collections; using System.Collections;
using NUnit.Framework;
using Amib.Threading;
/* /*
* The code below generates permutations. * The code below generates permutations.
* *
+6 -18
View File
@@ -1,5 +1,6 @@
using System;
using System.Threading; using System.Threading;
using Amib.Threading.Internal;
using NUnit.Framework; using NUnit.Framework;
using Amib.Threading; using Amib.Threading;
@@ -628,25 +629,12 @@ namespace SmartThreadPoolTests
Assert.IsTrue(success); 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 class WorkItemInfoComparer
{ {
private WorkItemInfo _neededWorkItemInfo; private WorkItemInfo _neededWorkItemInfo;
private object _state; private object _state;
private int _sleepTime = 0;
public int SleepTime public int SleepTime { get; set; }
{
get { return _sleepTime; }
set { _sleepTime = value; }
}
public WorkItemInfoComparer(WorkItemInfo workItemInfo) public WorkItemInfoComparer(WorkItemInfo workItemInfo)
{ {
@@ -665,12 +653,12 @@ namespace SmartThreadPoolTests
bool equals = object.Equals(_state, state); bool equals = object.Equals(_state, state);
if (equals) if (equals)
{ {
WorkItemInfo currentWorkItemInfo = GetCurrentWorkItemInfo(); WorkItemInfo currentWorkItemInfo = SmartThreadPool.CurrentThreadEntry.CurrentWorkItem.WorkItemInfo;
equals = CompareWorkItemInfo(currentWorkItemInfo, _neededWorkItemInfo); equals = CompareWorkItemInfo(currentWorkItemInfo, _neededWorkItemInfo);
} }
if (_sleepTime > 0) if (SleepTime > 0)
{ {
Thread.Sleep(_sleepTime); Thread.Sleep(SleepTime);
} }
return equals; return equals;
+10 -11
View File
@@ -1,4 +1,3 @@
using System;
using System.Threading; using System.Threading;
using NUnit.Framework; using NUnit.Framework;
@@ -28,7 +27,7 @@ namespace SmartThreadPoolTests
stpStartInfo.StartSuspended = true; stpStartInfo.StartSuspended = true;
SmartThreadPool stp = new SmartThreadPool(stpStartInfo); SmartThreadPool stp = new SmartThreadPool(stpStartInfo);
IWorkItemResult wir = stp.QueueWorkItem(delegate(object state) { return null; }); IWorkItemResult wir = stp.QueueWorkItem(arg => null);
wir.Cancel(); wir.Cancel();
@@ -59,7 +58,7 @@ namespace SmartThreadPoolTests
SmartThreadPool stp = new SmartThreadPool(); SmartThreadPool stp = new SmartThreadPool();
IWorkItemResult wir = stp.QueueWorkItem( IWorkItemResult wir = stp.QueueWorkItem(
delegate(object state) { waitToStart.Set(); Thread.Sleep(100); return null; } state => { waitToStart.Set(); Thread.Sleep(100); return null; }
); );
waitToStart.WaitOne(); waitToStart.WaitOne();
@@ -98,7 +97,7 @@ namespace SmartThreadPoolTests
SmartThreadPool stp = new SmartThreadPool(); SmartThreadPool stp = new SmartThreadPool();
IWorkItemResult wir = stp.QueueWorkItem( IWorkItemResult wir = stp.QueueWorkItem(
delegate(object state) { waitToStart.Set() ; Thread.Sleep(100); ++counter; return null; } state => { waitToStart.Set() ; Thread.Sleep(100); ++counter; return null; }
); );
waitToStart.WaitOne(); waitToStart.WaitOne();
@@ -137,7 +136,7 @@ namespace SmartThreadPoolTests
SmartThreadPool stp = new SmartThreadPool(); SmartThreadPool stp = new SmartThreadPool();
IWorkItemResult wir = stp.QueueWorkItem( IWorkItemResult wir = stp.QueueWorkItem(
delegate(object state) { state => {
waitToStart.Set(); waitToStart.Set();
Thread.Sleep(100); Thread.Sleep(100);
cancelled = SmartThreadPool.IsWorkItemCanceled; cancelled = SmartThreadPool.IsWorkItemCanceled;
@@ -174,7 +173,7 @@ namespace SmartThreadPoolTests
stpStartInfo.StartSuspended = true; stpStartInfo.StartSuspended = true;
SmartThreadPool stp = new SmartThreadPool(stpStartInfo); SmartThreadPool stp = new SmartThreadPool(stpStartInfo);
IWorkItemResult wir = stp.QueueWorkItem(delegate(object state) { return null; }); IWorkItemResult wir = stp.QueueWorkItem(state => { return null; });
int counter = 0; int counter = 0;
@@ -217,7 +216,7 @@ namespace SmartThreadPoolTests
{ {
SmartThreadPool stp = new SmartThreadPool(); SmartThreadPool stp = new SmartThreadPool();
IWorkItemResult wir = stp.QueueWorkItem( IWorkItemResult wir = stp.QueueWorkItem(
delegate(object state) { return 1; } state => 1
); );
stp.WaitForIdle(); stp.WaitForIdle();
@@ -250,7 +249,7 @@ namespace SmartThreadPoolTests
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
{ {
stp.QueueWorkItem( stp.QueueWorkItem(
delegate(object state) { Thread.Sleep(500); ++counter; return null; } state => { Thread.Sleep(500); ++counter; return null; }
); );
} }
@@ -285,7 +284,7 @@ namespace SmartThreadPoolTests
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
{ {
wig.QueueWorkItem( wig.QueueWorkItem(
delegate(object state) { Thread.Sleep(500); ++counter; return null; } state => { Thread.Sleep(500); ++counter; return null; }
); );
} }
@@ -324,14 +323,14 @@ namespace SmartThreadPoolTests
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
wig1.QueueWorkItem( wig1.QueueWorkItem(
delegate(object state) { Interlocked.Increment(ref counter1); Thread.Sleep(500); Interlocked.Increment(ref counter1); return null; } state => { Interlocked.Increment(ref counter1); Thread.Sleep(500); Interlocked.Increment(ref counter1); return null; }
); );
} }
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
wig2.QueueWorkItem( wig2.QueueWorkItem(
delegate(object state) { Thread.Sleep(500); Interlocked.Increment(ref counter2); return null; } state => { Thread.Sleep(500); Interlocked.Increment(ref counter2); return null; }
); );
} }
+3 -11
View File
@@ -1,6 +1,4 @@
using System; using System;
using System.Threading;
using NUnit.Framework; using NUnit.Framework;
using Amib.Threading; using Amib.Threading;
@@ -14,11 +12,7 @@ namespace SmartThreadPoolTests
[Category("TestChainedDelegates")] [Category("TestChainedDelegates")]
public class TestChainedDelegates public class TestChainedDelegates
{ {
public TestChainedDelegates() [Test]
{
}
[Test]
public void GoodCallback() public void GoodCallback()
{ {
SmartThreadPool stp = new SmartThreadPool(); SmartThreadPool stp = new SmartThreadPool();
@@ -67,10 +61,8 @@ namespace SmartThreadPoolTests
{ {
SmartThreadPool stp = new SmartThreadPool(); SmartThreadPool stp = new SmartThreadPool();
PostExecuteWorkItemCallback postExecuteWorkItemCallback = PostExecuteWorkItemCallback postExecuteWorkItemCallback = DoPostExecute;
new PostExecuteWorkItemCallback(DoPostExecute); postExecuteWorkItemCallback += DoPostExecute;
postExecuteWorkItemCallback +=
new PostExecuteWorkItemCallback(DoPostExecute);
stp.QueueWorkItem( stp.QueueWorkItem(
new WorkItemCallback(DoWork), new WorkItemCallback(DoWork),
+4 -10
View File
@@ -15,11 +15,7 @@ namespace SmartThreadPoolTests
[Category("TestConcurrencyChanges")] [Category("TestConcurrencyChanges")]
public class TestConcurrencyChanges public class TestConcurrencyChanges
{ {
public TestConcurrencyChanges() /// <summary>
{
}
/// <summary>
/// Example of waiting for idle /// Example of waiting for idle
/// </summary> /// </summary>
[Test] [Test]
@@ -27,8 +23,6 @@ namespace SmartThreadPoolTests
{ {
SmartThreadPool smartThreadPool = new SmartThreadPool(1 * 1000, 1, 0); SmartThreadPool smartThreadPool = new SmartThreadPool(1 * 1000, 1, 0);
bool success = false;
for (int i = 0; i < 100; ++i) for (int i = 0; i < 100; ++i)
{ {
smartThreadPool.QueueWorkItem( smartThreadPool.QueueWorkItem(
@@ -36,7 +30,7 @@ namespace SmartThreadPoolTests
null); null);
} }
success = WaitForMaxThreadsValue(smartThreadPool, 1, 1 * 1000); bool success = WaitForMaxThreadsValue(smartThreadPool, 1, 1 * 1000);
Assert.IsTrue(success); Assert.IsTrue(success);
smartThreadPool.MaxThreads = 5; smartThreadPool.MaxThreads = 5;
@@ -59,9 +53,9 @@ namespace SmartThreadPoolTests
{ {
SmartThreadPool smartThreadPool = new SmartThreadPool(1 * 1000, 25, 0); SmartThreadPool smartThreadPool = new SmartThreadPool(1 * 1000, 25, 0);
bool success = false;
success = WaitForMinThreadsValue(smartThreadPool, 0, 1 * 1000);
bool success = WaitForMinThreadsValue(smartThreadPool, 0, 1 * 1000);
Assert.IsTrue(success); Assert.IsTrue(success);
smartThreadPool.MinThreads = 5; smartThreadPool.MinThreads = 5;
-3
View File
@@ -1,7 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Text;
using Amib.Threading; using Amib.Threading;
using NUnit.Framework; using NUnit.Framework;
+5 -10
View File
@@ -1,5 +1,4 @@
using System; using System;
using System.Diagnostics;
using System.Threading; using System.Threading;
using NUnit.Framework; using NUnit.Framework;
@@ -111,9 +110,7 @@ namespace SmartThreadPoolTests
{ {
SmartThreadPool smartThreadPool = new SmartThreadPool(); SmartThreadPool smartThreadPool = new SmartThreadPool();
bool success = true; IWorkItemResult [] wirs = new IWorkItemResult[5];
IWorkItemResult [] wirs = new IWorkItemResult[5];
for(int i = 0; i < wirs.Length; ++i) for(int i = 0; i < wirs.Length; ++i)
{ {
@@ -122,7 +119,7 @@ namespace SmartThreadPoolTests
} }
bool timeout = !SmartThreadPool.WaitAll(wirs, 1500, true); bool timeout = !SmartThreadPool.WaitAll(wirs, 1500, true);
success = !timeout; bool success = !timeout;
smartThreadPool.Shutdown(); smartThreadPool.Shutdown();
@@ -138,9 +135,7 @@ namespace SmartThreadPoolTests
{ {
SmartThreadPool smartThreadPool = new SmartThreadPool(); SmartThreadPool smartThreadPool = new SmartThreadPool();
bool success = true; IWorkItemResult [] wirs = new IWorkItemResult[5];
IWorkItemResult [] wirs = new IWorkItemResult[5];
for(int i = 0; i < wirs.Length; ++i) for(int i = 0; i < wirs.Length; ++i)
{ {
@@ -149,7 +144,7 @@ namespace SmartThreadPoolTests
} }
bool timeout = !SmartThreadPool.WaitAll(wirs, 10, true); bool timeout = !SmartThreadPool.WaitAll(wirs, 10, true);
success = timeout; bool success = timeout;
smartThreadPool.Shutdown(); smartThreadPool.Shutdown();
@@ -193,7 +188,7 @@ namespace SmartThreadPoolTests
{ {
SmartThreadPool smartThreadPool = new SmartThreadPool(); SmartThreadPool smartThreadPool = new SmartThreadPool();
bool success = true; bool success;
IWorkItemResult [] wirs = new IWorkItemResult[5]; IWorkItemResult [] wirs = new IWorkItemResult[5];
+6 -18
View File
@@ -15,11 +15,7 @@ namespace PriorityQueueTests
[Category("TestPriorityQueue")] [Category("TestPriorityQueue")]
public class TestPriorityQueue public class TestPriorityQueue
{ {
public TestPriorityQueue() [Test]
{
}
[Test]
public void Init() public void Init()
{ {
PriorityQueue pq = new PriorityQueue(); PriorityQueue pq = new PriorityQueue();
@@ -149,20 +145,12 @@ namespace PriorityQueueTests
private class PriorityItem : IHasWorkItemPriority private class PriorityItem : IHasWorkItemPriority
{ {
private WorkItemPriority _workItemPriority; public PriorityItem(WorkItemPriority workItemPriority)
{
WorkItemPriority = workItemPriority;
}
public PriorityItem(WorkItemPriority workItemPriority) public WorkItemPriority WorkItemPriority { get; private set; }
{
_workItemPriority = workItemPriority;
}
public WorkItemPriority WorkItemPriority
{
get
{
return _workItemPriority;
}
}
} }
} }
+1 -5
View File
@@ -14,11 +14,7 @@ namespace SmartThreadPoolTests
[Category("TestStartSuspended")] [Category("TestStartSuspended")]
public class TestStartSuspended public class TestStartSuspended
{ {
public TestStartSuspended() [Test]
{
}
[Test]
public void StartSuspended() public void StartSuspended()
{ {
STPStartInfo stpStartInfo = new STPStartInfo(); STPStartInfo stpStartInfo = new STPStartInfo();
+4 -15
View File
@@ -9,16 +9,11 @@ namespace SmartThreadPoolTests
{ {
public class CallerState public class CallerState
{ {
private int _val = 0; public int Value { get; private set; }
public int Value
{
get { return _val; }
}
protected void IncValue() protected void IncValue()
{ {
++_val; ++Value;
} }
} }
@@ -55,11 +50,7 @@ namespace SmartThreadPoolTests
[Category("TestStateDispose")] [Category("TestStateDispose")]
public class TestStateDispose public class TestStateDispose
{ {
public TestStateDispose() /// <summary>
{
}
/// <summary>
/// Example of non disposable caller state /// Example of non disposable caller state
/// </summary> /// </summary>
[Test] [Test]
@@ -108,8 +99,6 @@ namespace SmartThreadPoolTests
SmartThreadPool smartThreadPool = new SmartThreadPool(stpStartInfo); SmartThreadPool smartThreadPool = new SmartThreadPool(stpStartInfo);
bool success = false;
CallerState nonDisposableCallerState = new NonDisposableCallerState(); CallerState nonDisposableCallerState = new NonDisposableCallerState();
CallerState disposableCallerState = new DisposableCallerState(); CallerState disposableCallerState = new DisposableCallerState();
@@ -124,7 +113,7 @@ namespace SmartThreadPoolTests
disposableCallerState); disposableCallerState);
wir1.GetResult(); wir1.GetResult();
success = (1 == nonDisposableCallerState.Value); bool success = (1 == nonDisposableCallerState.Value);
wir2.GetResult(); wir2.GetResult();
+3 -10
View File
@@ -1,5 +1,4 @@
using System; using System;
using System.Threading;
using NUnit.Framework; using NUnit.Framework;
@@ -31,8 +30,8 @@ namespace SmartThreadPoolTests
SmartThreadPool stp = new SmartThreadPool(); SmartThreadPool stp = new SmartThreadPool();
stp.OnThreadInitialization += new ThreadInitializationHandler(OnInitialization); stp.OnThreadInitialization += OnInitialization;
stp.OnThreadTermination += new ThreadTerminationHandler(OnTermination); stp.OnThreadTermination += OnTermination;
stp.QueueWorkItem(new WorkItemCallback(DoSomeWork), null); stp.QueueWorkItem(new WorkItemCallback(DoSomeWork), null);
@@ -72,13 +71,7 @@ namespace SmartThreadPoolTests
[ThreadStatic] [ThreadStatic]
private static ThreadContextState _threadContextState; private static ThreadContextState _threadContextState;
private int _counter = 0; public int Counter { get; set; }
public int Counter
{
get { return _counter; }
set { _counter = value; }
}
// Static member so it can be used anywhere in code of the work item method // Static member so it can be used anywhere in code of the work item method
public static ThreadContextState Current public static ThreadContextState Current
+1 -7
View File
@@ -1,6 +1,4 @@
using System; using System;
using System.Threading;
using NUnit.Framework; using NUnit.Framework;
using Amib.Threading; using Amib.Threading;
@@ -14,11 +12,7 @@ namespace WorkItemsGroupTests
[Category("Test WorkItemsGroup ChainedDelegates")] [Category("Test WorkItemsGroup ChainedDelegates")]
public class TestChainedDelegates public class TestChainedDelegates
{ {
public TestChainedDelegates() [Test]
{
}
[Test]
public void GoodCallback() public void GoodCallback()
{ {
SmartThreadPool smartThreadPool = new SmartThreadPool(); SmartThreadPool smartThreadPool = new SmartThreadPool();
+1 -5
View File
@@ -19,11 +19,7 @@ namespace WorkItemsGroupTests
private int _concurrencyPerWig; private int _concurrencyPerWig;
private bool _success; private bool _success;
public TestWIGConcurrency() [Test]
{
}
[Test]
public void TestConcurrencies() public void TestConcurrencies()
{ {
Concurrency(1, 1, 10); Concurrency(1, 1, 10);
+1 -7
View File
@@ -1,7 +1,5 @@
using System; using System;
using System.Threading; using System.Threading;
using System.Diagnostics;
using NUnit.Framework; using NUnit.Framework;
using Amib.Threading; using Amib.Threading;
@@ -15,11 +13,7 @@ namespace WorkItemsGroupTests
[Category("TestWIGConcurrencyChanges")] [Category("TestWIGConcurrencyChanges")]
public class TestWIGConcurrencyChanges public class TestWIGConcurrencyChanges
{ {
public TestWIGConcurrencyChanges() /// <summary>
{
}
/// <summary>
/// Example of waiting for idle /// Example of waiting for idle
/// </summary> /// </summary>
[Test] [Test]
+1
View File
@@ -1,3 +1,4 @@
using System;
using Amib.Threading; using Amib.Threading;
using NUnit.Framework; using NUnit.Framework;
+7 -14
View File
@@ -1,5 +1,4 @@
using System; using System;
using System.Diagnostics;
using System.Threading; using System.Threading;
using NUnit.Framework; using NUnit.Framework;
@@ -114,9 +113,7 @@ namespace WorkItemsGroupTests
SmartThreadPool smartThreadPool = new SmartThreadPool(); SmartThreadPool smartThreadPool = new SmartThreadPool();
IWorkItemsGroup workItemsGroup = smartThreadPool.CreateWorkItemsGroup(int.MaxValue); IWorkItemsGroup workItemsGroup = smartThreadPool.CreateWorkItemsGroup(int.MaxValue);
bool success = true; IWorkItemResult [] wirs = new IWorkItemResult[5];
IWorkItemResult [] wirs = new IWorkItemResult[5];
for(int i = 0; i < wirs.Length; ++i) for(int i = 0; i < wirs.Length; ++i)
{ {
@@ -125,7 +122,7 @@ namespace WorkItemsGroupTests
} }
bool timeout = !SmartThreadPool.WaitAll(wirs, 1500, true); bool timeout = !SmartThreadPool.WaitAll(wirs, 1500, true);
success = !timeout; bool success = !timeout;
smartThreadPool.Shutdown(); smartThreadPool.Shutdown();
@@ -142,9 +139,7 @@ namespace WorkItemsGroupTests
SmartThreadPool smartThreadPool = new SmartThreadPool(); SmartThreadPool smartThreadPool = new SmartThreadPool();
IWorkItemsGroup workItemsGroup = smartThreadPool.CreateWorkItemsGroup(int.MaxValue); IWorkItemsGroup workItemsGroup = smartThreadPool.CreateWorkItemsGroup(int.MaxValue);
bool success = true; IWorkItemResult [] wirs = new IWorkItemResult[5];
IWorkItemResult [] wirs = new IWorkItemResult[5];
for(int i = 0; i < wirs.Length; ++i) for(int i = 0; i < wirs.Length; ++i)
{ {
@@ -153,7 +148,7 @@ namespace WorkItemsGroupTests
} }
bool timeout = !SmartThreadPool.WaitAll(wirs, 10, true); bool timeout = !SmartThreadPool.WaitAll(wirs, 10, true);
success = timeout; bool success = timeout;
smartThreadPool.Shutdown(); smartThreadPool.Shutdown();
@@ -170,7 +165,7 @@ namespace WorkItemsGroupTests
SmartThreadPool smartThreadPool = new SmartThreadPool(); SmartThreadPool smartThreadPool = new SmartThreadPool();
IWorkItemsGroup workItemsGroup = smartThreadPool.CreateWorkItemsGroup(int.MaxValue); IWorkItemsGroup workItemsGroup = smartThreadPool.CreateWorkItemsGroup(int.MaxValue);
bool success = true; bool success;
IWorkItemResult [] wirs = new IWorkItemResult[5]; IWorkItemResult [] wirs = new IWorkItemResult[5];
@@ -199,9 +194,7 @@ namespace WorkItemsGroupTests
SmartThreadPool smartThreadPool = new SmartThreadPool(); SmartThreadPool smartThreadPool = new SmartThreadPool();
IWorkItemsGroup workItemsGroup = smartThreadPool.CreateWorkItemsGroup(int.MaxValue); IWorkItemsGroup workItemsGroup = smartThreadPool.CreateWorkItemsGroup(int.MaxValue);
bool success = true; IWorkItemResult [] wirs = new IWorkItemResult[5];
IWorkItemResult [] wirs = new IWorkItemResult[5];
for(int i = 0; i < wirs.Length; ++i) for(int i = 0; i < wirs.Length; ++i)
{ {
@@ -211,7 +204,7 @@ namespace WorkItemsGroupTests
int index = SmartThreadPool.WaitAny(wirs, 10, true); int index = SmartThreadPool.WaitAny(wirs, 10, true);
success = (index == WaitHandle.WaitTimeout); bool success = (index == WaitHandle.WaitTimeout);
smartThreadPool.Shutdown(); smartThreadPool.Shutdown();
-3
View File
@@ -1,6 +1,3 @@
using System;
using System.Threading;
using NUnit.Framework; using NUnit.Framework;
using Amib.Threading; using Amib.Threading;
+4 -15
View File
@@ -9,16 +9,11 @@ namespace WorkItemsGroupTests
{ {
public class CallerState public class CallerState
{ {
private int _val = 0; public int Value { get; private set; }
public int Value
{
get { return _val; }
}
protected void IncValue() protected void IncValue()
{ {
++_val; ++Value;
} }
} }
@@ -55,11 +50,7 @@ namespace WorkItemsGroupTests
[Category("WorkItemsGroup")] [Category("WorkItemsGroup")]
public class TestStateDispose public class TestStateDispose
{ {
public TestStateDispose() /// <summary>
{
}
/// <summary>
/// Example of non disposable caller state /// Example of non disposable caller state
/// </summary> /// </summary>
[Test] [Test]
@@ -112,8 +103,6 @@ namespace WorkItemsGroupTests
IWorkItemsGroup workItemsGroup = smartThreadPool.CreateWorkItemsGroup(int.MaxValue, wigStartInfo); IWorkItemsGroup workItemsGroup = smartThreadPool.CreateWorkItemsGroup(int.MaxValue, wigStartInfo);
bool success = false;
CallerState nonDisposableCallerState = new NonDisposableCallerState(); CallerState nonDisposableCallerState = new NonDisposableCallerState();
CallerState disposableCallerState = new DisposableCallerState(); CallerState disposableCallerState = new DisposableCallerState();
@@ -128,7 +117,7 @@ namespace WorkItemsGroupTests
disposableCallerState); disposableCallerState);
wir1.GetResult(); wir1.GetResult();
success = (1 == nonDisposableCallerState.Value); bool success = (1 == nonDisposableCallerState.Value);
wir2.GetResult(); wir2.GetResult();
+2 -9
View File
@@ -1,7 +1,5 @@
using System; using System;
using System.Threading; using System.Threading;
using System.Diagnostics;
using NUnit.Framework; using NUnit.Framework;
using Amib.Threading; using Amib.Threading;
@@ -15,11 +13,7 @@ namespace WorkItemsGroupTests
[Category("WorkItemsGroup")] [Category("WorkItemsGroup")]
public class TestWaitForIdle public class TestWaitForIdle
{ {
public TestWaitForIdle() /// <summary>
{
}
/// <summary>
/// Example of waiting for idle /// Example of waiting for idle
/// </summary> /// </summary>
[Test] [Test]
@@ -28,7 +22,6 @@ namespace WorkItemsGroupTests
SmartThreadPool smartThreadPool = new SmartThreadPool(10*1000, 25, 0); SmartThreadPool smartThreadPool = new SmartThreadPool(10*1000, 25, 0);
IWorkItemsGroup workItemsGroup = smartThreadPool.CreateWorkItemsGroup(int.MaxValue); IWorkItemsGroup workItemsGroup = smartThreadPool.CreateWorkItemsGroup(int.MaxValue);
bool success = false;
ManualResetEvent isRunning = new ManualResetEvent(false); ManualResetEvent isRunning = new ManualResetEvent(false);
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
@@ -36,7 +29,7 @@ namespace WorkItemsGroupTests
workItemsGroup.QueueWorkItem(delegate { isRunning.WaitOne(); }); workItemsGroup.QueueWorkItem(delegate { isRunning.WaitOne(); });
} }
success = !workItemsGroup.WaitForIdle(1000); bool success = !workItemsGroup.WaitForIdle(1000);
isRunning.Set(); isRunning.Set();
+2 -7
View File
@@ -15,11 +15,7 @@ namespace SmartThreadPoolTests
[Category("TestWaitForIdle")] [Category("TestWaitForIdle")]
public class TestWaitForIdle public class TestWaitForIdle
{ {
public TestWaitForIdle() /// <summary>
{
}
/// <summary>
/// Example of waiting for idle /// Example of waiting for idle
/// </summary> /// </summary>
[Test] [Test]
@@ -27,7 +23,6 @@ namespace SmartThreadPoolTests
{ {
SmartThreadPool smartThreadPool = new SmartThreadPool(10*1000, 25, 0); SmartThreadPool smartThreadPool = new SmartThreadPool(10*1000, 25, 0);
bool success = false;
ManualResetEvent isRunning = new ManualResetEvent(false); ManualResetEvent isRunning = new ManualResetEvent(false);
for(int i = 0; i < 4; ++i) for(int i = 0; i < 4; ++i)
@@ -35,7 +30,7 @@ namespace SmartThreadPoolTests
smartThreadPool.QueueWorkItem(delegate { isRunning.WaitOne(); }); smartThreadPool.QueueWorkItem(delegate { isRunning.WaitOne(); });
} }
success = !smartThreadPool.WaitForIdle(1000); bool success = !smartThreadPool.WaitForIdle(1000);
isRunning.Set(); isRunning.Set();
+1 -7
View File
@@ -1,7 +1,5 @@
using System; using System;
using System.Threading; using System.Threading;
using System.Diagnostics;
using NUnit.Framework; using NUnit.Framework;
using Amib.Threading; using Amib.Threading;
@@ -15,11 +13,7 @@ namespace WorkItemsGroupTests
[Category("TestWorkItemsGroups")] [Category("TestWorkItemsGroups")]
public class TestWorkItemsGroups public class TestWorkItemsGroups
{ {
public TestWorkItemsGroups() [Test]
{
}
[Test]
public void BlockingCall() public void BlockingCall()
{ {
SmartThreadPool smartThreadPool = new SmartThreadPool(); SmartThreadPool smartThreadPool = new SmartThreadPool();
+3 -13
View File
@@ -1,12 +1,6 @@
using System;
using NUnit.Framework; using NUnit.Framework;
using Amib.Threading;
using Amib.Threading.Internal; using Amib.Threading.Internal;
using SmartThreadPoolTests;
namespace PriorityQueueTests namespace PriorityQueueTests
{ {
/// <summary> /// <summary>
@@ -16,11 +10,7 @@ namespace PriorityQueueTests
[Category("TestWorkItemsQueue")] [Category("TestWorkItemsQueue")]
public class TestWorkItemsQueue public class TestWorkItemsQueue
{ {
public TestWorkItemsQueue() [Test]
{
}
[Test]
public void Init() public void Init()
{ {
} }
@@ -32,7 +22,7 @@ namespace PriorityQueueTests
Assert.AreEqual(0, q.WaitersCount); Assert.AreEqual(0, q.WaitersCount);
WorkItemsQueue.WaiterEntry we1 = new Amib.Threading.Internal.WorkItemsQueue.WaiterEntry(); WorkItemsQueue.WaiterEntry we1 = new WorkItemsQueue.WaiterEntry();
q.PushWaiter(we1); q.PushWaiter(we1);
Assert.AreEqual(1, q.WaitersCount); Assert.AreEqual(1, q.WaitersCount);
@@ -41,7 +31,7 @@ namespace PriorityQueueTests
Assert.AreEqual(1, q.WaitersCount); Assert.AreEqual(1, q.WaitersCount);
WorkItemsQueue.WaiterEntry we2 = new Amib.Threading.Internal.WorkItemsQueue.WaiterEntry(); WorkItemsQueue.WaiterEntry we2 = new WorkItemsQueue.WaiterEntry();
q.PushWaiter(we2); q.PushWaiter(we2);
Assert.AreEqual(2, q.WaitersCount); Assert.AreEqual(2, q.WaitersCount);
+2
View File
@@ -25,6 +25,7 @@ Global
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D81DD596-C71F-4AC2-816C-63C19589E7E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D81DD596-C71F-4AC2-816C-63C19589E7E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D81DD596-C71F-4AC2-816C-63C19589E7E0}.Debug|Any CPU.Build.0 = Debug|Any CPU {D81DD596-C71F-4AC2-816C-63C19589E7E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D81DD596-C71F-4AC2-816C-63C19589E7E0}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{D81DD596-C71F-4AC2-816C-63C19589E7E0}.Release|Any CPU.ActiveCfg = Release|Any CPU {D81DD596-C71F-4AC2-816C-63C19589E7E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D81DD596-C71F-4AC2-816C-63C19589E7E0}.Release|Any CPU.Build.0 = Release|Any CPU {D81DD596-C71F-4AC2-816C-63C19589E7E0}.Release|Any CPU.Build.0 = Release|Any CPU
{74D4C33F-7CC8-4B2A-A7DF-D8B6E63B6EBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {74D4C33F-7CC8-4B2A-A7DF-D8B6E63B6EBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@@ -53,6 +54,7 @@ Global
{DC005A64-FAE9-4CFA-ADC8-F1D1FE7FE6CD}.Release|Any CPU.Build.0 = Release|Any CPU {DC005A64-FAE9-4CFA-ADC8-F1D1FE7FE6CD}.Release|Any CPU.Build.0 = Release|Any CPU
{356114BA-5F10-4DB6-9971-987CE11F765F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {356114BA-5F10-4DB6-9971-987CE11F765F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{356114BA-5F10-4DB6-9971-987CE11F765F}.Debug|Any CPU.Build.0 = Debug|Any CPU {356114BA-5F10-4DB6-9971-987CE11F765F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{356114BA-5F10-4DB6-9971-987CE11F765F}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{356114BA-5F10-4DB6-9971-987CE11F765F}.Release|Any CPU.ActiveCfg = Release|Any CPU {356114BA-5F10-4DB6-9971-987CE11F765F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{356114BA-5F10-4DB6-9971-987CE11F765F}.Release|Any CPU.Build.0 = Release|Any CPU {356114BA-5F10-4DB6-9971-987CE11F765F}.Release|Any CPU.Build.0 = Release|Any CPU
{356114BA-5F10-4DB6-9971-987CE11F765F}.Release|Any CPU.Deploy.0 = Release|Any CPU {356114BA-5F10-4DB6-9971-987CE11F765F}.Release|Any CPU.Deploy.0 = Release|Any CPU
+14
View File
@@ -0,0 +1,14 @@
namespace Amib.Threading.Internal
{
internal class CanceledWorkItemsGroup
{
public readonly static CanceledWorkItemsGroup NotCanceledWorkItemsGroup = new CanceledWorkItemsGroup();
public CanceledWorkItemsGroup()
{
IsCanceled = false;
}
public bool IsCanceled { get; set; }
}
}
+5 -5
View File
@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading; using System.Threading;
using System.Diagnostics;
#if (WindowsCE)
using System;
using System.Runtime.InteropServices;
#endif
namespace Amib.Threading.Internal namespace Amib.Threading.Internal
{ {
+3 -3
View File
@@ -10,7 +10,7 @@ namespace Amib.Threading
/// <summary> /// <summary>
/// Represents an exception in case IWorkItemResult.GetResult has been canceled /// Represents an exception in case IWorkItemResult.GetResult has been canceled
/// </summary> /// </summary>
public sealed partial class WorkItemCancelException : ApplicationException public sealed partial class WorkItemCancelException : Exception
{ {
public WorkItemCancelException() public WorkItemCancelException()
{ {
@@ -30,7 +30,7 @@ namespace Amib.Threading
/// <summary> /// <summary>
/// Represents an exception in case IWorkItemResult.GetResult has been timed out /// Represents an exception in case IWorkItemResult.GetResult has been timed out
/// </summary> /// </summary>
public sealed partial class WorkItemTimeoutException : ApplicationException public sealed partial class WorkItemTimeoutException : Exception
{ {
public WorkItemTimeoutException() public WorkItemTimeoutException()
{ {
@@ -50,7 +50,7 @@ namespace Amib.Threading
/// <summary> /// <summary>
/// Represents an exception in case IWorkItemResult.GetResult has been timed out /// Represents an exception in case IWorkItemResult.GetResult has been timed out
/// </summary> /// </summary>
public sealed partial class WorkItemResultException : ApplicationException public sealed partial class WorkItemResultException : Exception
{ {
public WorkItemResultException() public WorkItemResultException()
{ {
+27
View File
@@ -0,0 +1,27 @@
namespace Amib.Threading.Internal
{
/// <summary>
/// An internal delegate to call when the WorkItem starts or completes
/// </summary>
internal delegate void WorkItemStateCallback(WorkItem workItem);
internal interface IInternalWorkItemResult
{
event WorkItemStateCallback OnWorkItemStarted;
event WorkItemStateCallback OnWorkItemCompleted;
}
internal interface IInternalWaitableResult
{
/// <summary>
/// This method is intent for internal use.
/// </summary>
IWorkItemResult GetWorkItemResult();
}
public interface IHasWorkItemPriority
{
WorkItemPriority WorkItemPriority { get; }
}
}
+2 -19
View File
@@ -2,9 +2,6 @@
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Amib.Threading")] [assembly: AssemblyTitle("Amib.Threading")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
@@ -13,23 +10,9 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCopyright("")] [assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("c764a3de-c4f8-434d-85b5-a09830d1e44f")] [assembly: Guid("c764a3de-c4f8-434d-85b5-a09830d1e44f")]
[assembly: AssemblyVersion("2.0.1.0")]
[assembly: InternalsVisibleTo("STPTests")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("2.0.0.0")]
+3
View File
@@ -1,5 +1,8 @@
using System; using System;
#if !(WindowsCE)
using System.Diagnostics; using System.Diagnostics;
#endif
namespace Amib.Threading.Internal namespace Amib.Threading.Internal
{ {
+88 -58
View File
@@ -8,83 +8,112 @@ namespace Amib.Threading
/// </summary> /// </summary>
public class STPStartInfo : WIGStartInfo public class STPStartInfo : WIGStartInfo
{ {
private int _idleTimeout = SmartThreadPool.DefaultIdleTimeout; private int _idleTimeout;
private int _minWorkerThreads = SmartThreadPool.DefaultMinWorkerThreads; private int _minWorkerThreads;
private int _maxWorkerThreads = SmartThreadPool.DefaultMaxWorkerThreads; private int _maxWorkerThreads;
private ThreadPriority _threadPriority = SmartThreadPool.DefaultThreadPriority; private ThreadPriority _threadPriority;
private string _pcInstanceName = SmartThreadPool.DefaultPerformanceCounterInstanceName; private string _performanceCounterInstanceName;
public STPStartInfo() public STPStartInfo()
{ {
_performanceCounterInstanceName = SmartThreadPool.DefaultPerformanceCounterInstanceName;
_threadPriority = SmartThreadPool.DefaultThreadPriority;
_maxWorkerThreads = SmartThreadPool.DefaultMaxWorkerThreads;
_idleTimeout = SmartThreadPool.DefaultIdleTimeout;
_minWorkerThreads = SmartThreadPool.DefaultMinWorkerThreads;
} }
public STPStartInfo(STPStartInfo stpStartInfo) public STPStartInfo(STPStartInfo stpStartInfo)
: base(stpStartInfo) : base(stpStartInfo)
{ {
_idleTimeout = stpStartInfo._idleTimeout; _idleTimeout = stpStartInfo.IdleTimeout;
_minWorkerThreads = stpStartInfo._minWorkerThreads; _minWorkerThreads = stpStartInfo.MinWorkerThreads;
_maxWorkerThreads = stpStartInfo._maxWorkerThreads; _maxWorkerThreads = stpStartInfo.MaxWorkerThreads;
_threadPriority = stpStartInfo._threadPriority; _threadPriority = stpStartInfo.ThreadPriority;
_pcInstanceName = stpStartInfo._pcInstanceName; _performanceCounterInstanceName = stpStartInfo.PerformanceCounterInstanceName;
} }
/// <summary>
/// Get/Set the idle timeout in milliseconds. /// <summary>
/// If a thread is idle (starved) longer than IdleTimeout then it may quit. /// Get/Set the idle timeout in milliseconds.
/// </summary> /// If a thread is idle (starved) longer than IdleTimeout then it may quit.
public virtual int IdleTimeout /// </summary>
{ public virtual int IdleTimeout
get { return _idleTimeout; } {
set { _idleTimeout = value; } get { return _idleTimeout; }
} set
{
ThrowIfReadOnly();
_idleTimeout = value;
}
}
/// <summary>
/// Get/Set the lower limit of threads in the pool.
/// </summary>
public virtual int MinWorkerThreads
{
get { return _minWorkerThreads; }
set { _minWorkerThreads = value; }
}
/// <summary> /// <summary>
/// Get/Set the upper limit of threads in the pool. /// Get/Set the lower limit of threads in the pool.
/// </summary> /// </summary>
public virtual int MaxWorkerThreads public virtual int MinWorkerThreads
{ {
get { return _maxWorkerThreads; } get { return _minWorkerThreads; }
set { _maxWorkerThreads = value; } set
} {
ThrowIfReadOnly();
_minWorkerThreads = value;
}
}
/// <summary>
/// Get/Set the scheduling priority of the threads in the pool.
/// The Os handles the scheduling.
/// </summary>
public virtual ThreadPriority ThreadPriority
{
get { return _threadPriority; }
set { _threadPriority = value; }
}
/// <summary> /// <summary>
/// Get/Set the performance counter instance name of this SmartThreadPool /// Get/Set the upper limit of threads in the pool.
/// The default is null which indicate not to use performance counters at all. /// </summary>
/// </summary> public virtual int MaxWorkerThreads
public virtual string PerformanceCounterInstanceName {
{ get { return _maxWorkerThreads; }
get { return _pcInstanceName; } set
set { _pcInstanceName = value; } {
} ThrowIfReadOnly();
_maxWorkerThreads = value;
}
}
/// <summary>
/// <summary>
/// Get/Set the scheduling priority of the threads in the pool.
/// The Os handles the scheduling.
/// </summary>
public virtual ThreadPriority ThreadPriority
{
get { return _threadPriority; }
set
{
ThrowIfReadOnly();
_threadPriority = value;
}
}
/// <summary>
/// Get/Set the performance counter instance name of this SmartThreadPool
/// The default is null which indicate not to use performance counters at all.
/// </summary>
public virtual string PerformanceCounterInstanceName
{
get { return _performanceCounterInstanceName; }
set
{
ThrowIfReadOnly();
_performanceCounterInstanceName = value;
}
}
/// <summary>
/// Get a readonly version of this STPStartInfo. /// Get a readonly version of this STPStartInfo.
/// </summary> /// </summary>
/// <returns>Returns a readonly reference to this STPStartInfo</returns> /// <returns>Returns a readonly reference to this STPStartInfo</returns>
public new STPStartInfo AsReadOnly() public new STPStartInfo AsReadOnly()
{ {
return new STPStartInfoRO(this); return new STPStartInfo(this) { _readOnly = true };
} }
/*
#region STPStartInfoRO class #region STPStartInfoRO class
private class STPStartInfoRO : STPStartInfo private class STPStartInfoRO : STPStartInfo
@@ -221,5 +250,6 @@ namespace Amib.Threading
} }
#endregion #endregion
*/
} }
} }
@@ -0,0 +1,60 @@
using System;
using Amib.Threading.Internal;
namespace Amib.Threading
{
public partial class SmartThreadPool
{
#region ThreadEntry class
internal class ThreadEntry
{
/// <summary>
/// The thread creation time
/// The value is stored as UTC value.
/// </summary>
private readonly DateTime _creationTime;
/// <summary>
/// The last time this thread has been running
/// It is updated by IAmAlive() method
/// The value is stored as UTC value.
/// </summary>
private DateTime _lastAliveTime;
/// <summary>
/// A reference from each thread in the thread pool to its SmartThreadPool
/// object container.
/// With this variable a thread can know whatever it belongs to a
/// SmartThreadPool.
/// </summary>
private readonly SmartThreadPool _associatedSmartThreadPool;
/// <summary>
/// A reference to the current work item a thread from the thread pool
/// is executing.
/// </summary>
public WorkItem CurrentWorkItem { get; set; }
public ThreadEntry(SmartThreadPool stp)
{
_associatedSmartThreadPool = stp;
_creationTime = DateTime.UtcNow;
_lastAliveTime = DateTime.MinValue;
}
public SmartThreadPool AssociatedSmartThreadPool
{
get { return _associatedSmartThreadPool; }
}
public void IAmAlive()
{
_lastAliveTime = DateTime.UtcNow;
}
}
#endregion
}
}
+43 -94
View File
@@ -82,7 +82,7 @@ namespace Amib.Threading
/// <summary> /// <summary>
/// Smart thread pool class. /// Smart thread pool class.
/// </summary> /// </summary>
public class SmartThreadPool : WorkItemsGroupBase, IDisposable public partial class SmartThreadPool : WorkItemsGroupBase, IDisposable
{ {
#region Public Default Constants #region Public Default Constants
@@ -156,61 +156,6 @@ namespace Amib.Threading
#endregion #endregion
#region ThreadEntry class
private class ThreadEntry
{
/// <summary>
/// The thread creation time
/// </summary>
private DateTime _creationTime;
/// <summary>
/// The last time this thread has been running
/// It is updated by IAmAlive() method
/// </summary>
private DateTime _lastAliveTime;
/// <summary>
/// A reference to the current work item a thread from the thread pool
/// is executing.
/// </summary>
private WorkItem _currentWorkItem;
/// <summary>
/// A reference from each thread in the thread pool to its SmartThreadPool
/// object container.
/// With this variable a thread can know whatever it belongs to a
/// SmartThreadPool.
/// </summary>
private SmartThreadPool _associatedSmartThreadPool;
public ThreadEntry(SmartThreadPool stp)
{
_associatedSmartThreadPool = stp;
_creationTime = DateTime.Now;
_lastAliveTime = DateTime.MinValue;
}
public WorkItem CurrentWorkItem
{
get { return _currentWorkItem; }
set { _currentWorkItem = value; }
}
public SmartThreadPool AssociatedSmartThreadPool
{
get { return _associatedSmartThreadPool; }
}
public void IAmAlive()
{
_lastAliveTime = DateTime.Now;
}
}
#endregion
#region Member Variables #region Member Variables
/// <summary> /// <summary>
@@ -234,17 +179,11 @@ namespace Amib.Threading
/// </summary> /// </summary>
private int _inUseWorkerThreads; private int _inUseWorkerThreads;
/// <summary>
/// Start information to use.
/// It is simpler than providing many constructors.
/// </summary>
private STPStartInfo _stpStartInfo = new STPStartInfo();
/// <summary> /// <summary>
/// Stored the original reference to the provided _stpStartInfo. /// Stores a copy of the original STPStartInfo.
/// It is used to change the MinThread and MaxThreads /// It is used to change the MinThread and MaxThreads
/// </summary> /// </summary>
private STPStartInfo _stpStartInfoRW; private STPStartInfo _stpStartInfo;
/// <summary> /// <summary>
/// Total number of work items that are stored in the work items queue /// Total number of work items that are stored in the work items queue
@@ -338,7 +277,7 @@ namespace Amib.Threading
/// A reference to the current work item a thread from the thread pool /// A reference to the current work item a thread from the thread pool
/// is executing. /// is executing.
/// </summary> /// </summary>
private static ThreadEntry CurrentThreadEntry internal static ThreadEntry CurrentThreadEntry
{ {
#if (WindowsCE) #if (WindowsCE)
get get
@@ -369,7 +308,8 @@ namespace Amib.Threading
/// </summary> /// </summary>
public SmartThreadPool() public SmartThreadPool()
{ {
Initialize(); _stpStartInfo = new STPStartInfo();
Initialize();
} }
/// <summary> /// <summary>
@@ -378,7 +318,10 @@ namespace Amib.Threading
/// <param name="idleTimeout">Idle timeout in milliseconds</param> /// <param name="idleTimeout">Idle timeout in milliseconds</param>
public SmartThreadPool(int idleTimeout) public SmartThreadPool(int idleTimeout)
{ {
_stpStartInfo.IdleTimeout = idleTimeout; _stpStartInfo = new STPStartInfo
{
IdleTimeout = idleTimeout,
};
Initialize(); Initialize();
} }
@@ -391,8 +334,11 @@ namespace Amib.Threading
int idleTimeout, int idleTimeout,
int maxWorkerThreads) int maxWorkerThreads)
{ {
_stpStartInfo.IdleTimeout = idleTimeout; _stpStartInfo = new STPStartInfo
_stpStartInfo.MaxWorkerThreads = maxWorkerThreads; {
IdleTimeout = idleTimeout,
MaxWorkerThreads = maxWorkerThreads,
};
Initialize(); Initialize();
} }
@@ -407,9 +353,12 @@ namespace Amib.Threading
int maxWorkerThreads, int maxWorkerThreads,
int minWorkerThreads) int minWorkerThreads)
{ {
_stpStartInfo.IdleTimeout = idleTimeout; _stpStartInfo = new STPStartInfo
_stpStartInfo.MaxWorkerThreads = maxWorkerThreads; {
_stpStartInfo.MinWorkerThreads = minWorkerThreads; IdleTimeout = idleTimeout,
MaxWorkerThreads = maxWorkerThreads,
MinWorkerThreads = minWorkerThreads,
};
Initialize(); Initialize();
} }
@@ -428,11 +377,8 @@ namespace Amib.Threading
Name = "SmartThreadPool"; Name = "SmartThreadPool";
ValidateSTPStartInfo(); ValidateSTPStartInfo();
// _stpStartInfoRW holds a read/write reference to the original _stpStartInfo. // _stpStartInfoRW stores a read/write copy of the STPStartInfo.
_stpStartInfoRW = _stpStartInfo; // Actually only MaxWorkerThreads and MinWorkerThreads are overwritten
// From now on _stpStartInfo is readonly
_stpStartInfo = _stpStartInfo.AsReadOnly();
_isSuspended = _stpStartInfo.StartSuspended; _isSuspended = _stpStartInfo.StartSuspended;
@@ -467,7 +413,7 @@ namespace Amib.Threading
private void StartOptimalNumberOfThreads() private void StartOptimalNumberOfThreads()
{ {
int threadsCount = Math.Max(_workItemsQueue.Count, _stpStartInfo.MinWorkerThreads); int threadsCount = Math.Max(_workItemsQueue.Count, _stpStartInfo.MinWorkerThreads);
threadsCount = Math.Min(threadsCount, _stpStartInfo.MaxWorkerThreads); threadsCount = Math.Min(threadsCount, _stpStartInfo.MaxWorkerThreads);
threadsCount -= _workerThreads.Count; threadsCount -= _workerThreads.Count;
if (threadsCount > 0) if (threadsCount > 0)
{ {
@@ -477,19 +423,19 @@ namespace Amib.Threading
private void ValidateSTPStartInfo() private void ValidateSTPStartInfo()
{ {
if (_stpStartInfo.MinWorkerThreads < 0) if (_stpStartInfo.MinWorkerThreads < 0)
{ {
throw new ArgumentOutOfRangeException( throw new ArgumentOutOfRangeException(
"MinWorkerThreads", "MinWorkerThreads cannot be negative"); "MinWorkerThreads", "MinWorkerThreads cannot be negative");
} }
if (_stpStartInfo.MaxWorkerThreads <= 0) if (_stpStartInfo.MaxWorkerThreads <= 0)
{ {
throw new ArgumentOutOfRangeException( throw new ArgumentOutOfRangeException(
"MaxWorkerThreads", "MaxWorkerThreads must be greater than zero"); "MaxWorkerThreads", "MaxWorkerThreads must be greater than zero");
} }
if (_stpStartInfo.MinWorkerThreads > _stpStartInfo.MaxWorkerThreads) if (_stpStartInfo.MinWorkerThreads > _stpStartInfo.MaxWorkerThreads)
{ {
throw new ArgumentOutOfRangeException( throw new ArgumentOutOfRangeException(
"MinWorkerThreads, maxWorkerThreads", "MinWorkerThreads, maxWorkerThreads",
@@ -517,8 +463,8 @@ namespace Amib.Threading
/// </returns> /// </returns>
private WorkItem Dequeue() private WorkItem Dequeue()
{ {
WorkItem workItem = WorkItem workItem =
_workItemsQueue.DequeueWorkItem(_stpStartInfo.IdleTimeout, _shuttingDownEvent); _workItemsQueue.DequeueWorkItem(_stpStartInfo.IdleTimeout, _shuttingDownEvent);
return workItem; return workItem;
} }
@@ -628,7 +574,7 @@ namespace Amib.Threading
for(int i = 0; i < threadsCount; ++i) for(int i = 0; i < threadsCount; ++i)
{ {
// Don't create more threads then the upper limit // Don't create more threads then the upper limit
if (_workerThreads.Count >= _stpStartInfo.MaxWorkerThreads) if (_workerThreads.Count >= _stpStartInfo.MaxWorkerThreads)
{ {
return; return;
} }
@@ -639,7 +585,7 @@ namespace Amib.Threading
// Configure the new thread and start it // Configure the new thread and start it
workerThread.Name = "STP " + Name + " Thread #" + _threadCounter; workerThread.Name = "STP " + Name + " Thread #" + _threadCounter;
workerThread.IsBackground = true; workerThread.IsBackground = true;
workerThread.Priority = _stpStartInfo.ThreadPriority; workerThread.Priority = _stpStartInfo.ThreadPriority;
workerThread.Start(); workerThread.Start();
++_threadCounter; ++_threadCounter;
@@ -703,11 +649,11 @@ namespace Amib.Threading
if (null == workItem) if (null == workItem)
{ {
// Double lock for quit. // Double lock for quit.
if (_workerThreads.Count > _stpStartInfo.MinWorkerThreads) if (_workerThreads.Count > _stpStartInfo.MinWorkerThreads)
{ {
lock(_workerThreads.SyncRoot) lock(_workerThreads.SyncRoot)
{ {
if (_workerThreads.Count > _stpStartInfo.MinWorkerThreads) if (_workerThreads.Count > _stpStartInfo.MinWorkerThreads)
{ {
// Inform that the thread is quiting and then quit. // Inform that the thread is quiting and then quit.
// This method must be called within this lock or else // This method must be called within this lock or else
@@ -1180,7 +1126,7 @@ namespace Amib.Threading
/// <returns>A reference to the WorkItemsGroup</returns> /// <returns>A reference to the WorkItemsGroup</returns>
public IWorkItemsGroup CreateWorkItemsGroup(int concurrency) public IWorkItemsGroup CreateWorkItemsGroup(int concurrency)
{ {
IWorkItemsGroup workItemsGroup = new WorkItemsGroup(this, concurrency, _stpStartInfo); IWorkItemsGroup workItemsGroup = new WorkItemsGroup(this, concurrency, _stpStartInfo);
return workItemsGroup; return workItemsGroup;
} }
@@ -1297,9 +1243,9 @@ namespace Amib.Threading
Debug.Assert(value <= _stpStartInfo.MaxWorkerThreads); Debug.Assert(value <= _stpStartInfo.MaxWorkerThreads);
if (_stpStartInfo.MaxWorkerThreads < value) if (_stpStartInfo.MaxWorkerThreads < value)
{ {
_stpStartInfoRW.MaxWorkerThreads = value; _stpStartInfo.MaxWorkerThreads = value;
} }
_stpStartInfoRW.MinWorkerThreads = value; _stpStartInfo.MinWorkerThreads = value;
StartOptimalNumberOfThreads(); StartOptimalNumberOfThreads();
} }
} }
@@ -1321,9 +1267,9 @@ namespace Amib.Threading
Debug.Assert(value >= _stpStartInfo.MinWorkerThreads); Debug.Assert(value >= _stpStartInfo.MinWorkerThreads);
if (_stpStartInfo.MinWorkerThreads > value) if (_stpStartInfo.MinWorkerThreads > value)
{ {
_stpStartInfoRW.MinWorkerThreads = value; _stpStartInfo.MinWorkerThreads = value;
} }
_stpStartInfoRW.MaxWorkerThreads = value; _stpStartInfo.MaxWorkerThreads = value;
StartOptimalNumberOfThreads(); StartOptimalNumberOfThreads();
} }
} }
@@ -1371,7 +1317,10 @@ namespace Amib.Threading
/// </summary> /// </summary>
public STPStartInfo STPStartInfo public STPStartInfo STPStartInfo
{ {
get { return _stpStartInfo; } get
{
return _stpStartInfo.AsReadOnly();
}
} }
#endregion #endregion
@@ -1451,7 +1400,7 @@ namespace Amib.Threading
/// </summary> /// </summary>
public override WIGStartInfo WIGStartInfo public override WIGStartInfo WIGStartInfo
{ {
get { return _stpStartInfo; } get { return _stpStartInfo.AsReadOnly(); }
} }
/// <summary> /// <summary>
+4
View File
@@ -49,16 +49,20 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="WorkItem.WorkItemResult.cs" />
<Compile Include="CallerThreadContext.cs" /> <Compile Include="CallerThreadContext.cs" />
<Compile Include="CanceledWorkItemsGroup.cs" />
<Compile Include="EventWaitHandleFactory.cs" /> <Compile Include="EventWaitHandleFactory.cs" />
<Compile Include="Exceptions.cs" /> <Compile Include="Exceptions.cs" />
<Compile Include="Interfaces.cs" /> <Compile Include="Interfaces.cs" />
<Compile Include="InternalInterfaces.cs" />
<Compile Include="PriorityQueue.cs" /> <Compile Include="PriorityQueue.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SmartThreadPool.cs" /> <Compile Include="SmartThreadPool.cs" />
<Compile Include="STPPerformanceCounter.cs" /> <Compile Include="STPPerformanceCounter.cs" />
<Compile Include="STPStartInfo.cs" /> <Compile Include="STPStartInfo.cs" />
<Compile Include="SynchronizedDictionary.cs" /> <Compile Include="SynchronizedDictionary.cs" />
<Compile Include="SmartThreadPool.ThreadEntry.cs" />
<Compile Include="WIGStartInfo.cs" /> <Compile Include="WIGStartInfo.cs" />
<Compile Include="WorkItem.cs" /> <Compile Include="WorkItem.cs" />
<Compile Include="WorkItemFactory.cs" /> <Compile Include="WorkItemFactory.cs" />
+5 -1
View File
@@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion> <ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion> <SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{D81DD596-C71F-4AC2-816C-63C19589E7E0}</ProjectGuid> <ProjectGuid>{D81DD596-C71F-4AC2-816C-63C19589E7E0}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
@@ -72,18 +72,22 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="CallerThreadContext.cs" /> <Compile Include="CallerThreadContext.cs" />
<Compile Include="CanceledWorkItemsGroup.cs" />
<Compile Include="EventWaitHandle.cs" /> <Compile Include="EventWaitHandle.cs" />
<Compile Include="EventWaitHandleFactory.cs" /> <Compile Include="EventWaitHandleFactory.cs" />
<Compile Include="Exceptions.cs" /> <Compile Include="Exceptions.cs" />
<Compile Include="Interfaces.cs" /> <Compile Include="Interfaces.cs" />
<Compile Include="InternalInterfaces.cs" />
<Compile Include="PriorityQueue.cs" /> <Compile Include="PriorityQueue.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SmartThreadPool.cs" /> <Compile Include="SmartThreadPool.cs" />
<Compile Include="SmartThreadPool.ThreadEntry.cs" />
<Compile Include="STPPerformanceCounter.cs" /> <Compile Include="STPPerformanceCounter.cs" />
<Compile Include="STPStartInfo.cs" /> <Compile Include="STPStartInfo.cs" />
<Compile Include="SynchronizedDictionary.cs" /> <Compile Include="SynchronizedDictionary.cs" />
<Compile Include="WIGStartInfo.cs" /> <Compile Include="WIGStartInfo.cs" />
<Compile Include="WorkItem.cs" /> <Compile Include="WorkItem.cs" />
<Compile Include="WorkItem.WorkItemResult.cs" />
<Compile Include="WorkItemFactory.cs" /> <Compile Include="WorkItemFactory.cs" />
<Compile Include="WorkItemInfo.cs" /> <Compile Include="WorkItemInfo.cs" />
<Compile Include="WorkItemResultTWrapper.cs" /> <Compile Include="WorkItemResultTWrapper.cs" />
+148 -95
View File
@@ -7,116 +7,168 @@ namespace Amib.Threading
/// </summary> /// </summary>
public class WIGStartInfo public class WIGStartInfo
{ {
private bool _useCallerCallContext = SmartThreadPool.DefaultUseCallerCallContext; private bool _useCallerCallContext;
private bool _useCallerHttpContext = SmartThreadPool.DefaultUseCallerHttpContext; private bool _useCallerHttpContext;
private bool _disposeOfStateObjects = SmartThreadPool.DefaultDisposeOfStateObjects; private bool _disposeOfStateObjects;
private CallToPostExecute _callToPostExecute = SmartThreadPool.DefaultCallToPostExecute; private CallToPostExecute _callToPostExecute;
private PostExecuteWorkItemCallback _postExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback; private PostExecuteWorkItemCallback _postExecuteWorkItemCallback;
private WorkItemPriority _workItemPriority = SmartThreadPool.DefaultWorkItemPriority; private bool _startSuspended;
private bool _startSuspended = SmartThreadPool.DefaultStartSuspended; private WorkItemPriority _workItemPriority;
private bool _fillStateWithArgs = SmartThreadPool.DefaultFillStateWithArgs; private bool _fillStateWithArgs;
public WIGStartInfo() protected bool _readOnly;
public WIGStartInfo()
{ {
_fillStateWithArgs = SmartThreadPool.DefaultFillStateWithArgs;
_workItemPriority = SmartThreadPool.DefaultWorkItemPriority;
_startSuspended = SmartThreadPool.DefaultStartSuspended;
_postExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback;
_callToPostExecute = SmartThreadPool.DefaultCallToPostExecute;
_disposeOfStateObjects = SmartThreadPool.DefaultDisposeOfStateObjects;
_useCallerHttpContext = SmartThreadPool.DefaultUseCallerHttpContext;
_useCallerCallContext = SmartThreadPool.DefaultUseCallerCallContext;
} }
public WIGStartInfo(WIGStartInfo wigStartInfo) public WIGStartInfo(WIGStartInfo wigStartInfo)
{ {
_useCallerCallContext = wigStartInfo._useCallerCallContext; _useCallerCallContext = wigStartInfo.UseCallerCallContext;
_useCallerHttpContext = wigStartInfo._useCallerHttpContext; _useCallerHttpContext = wigStartInfo.UseCallerHttpContext;
_disposeOfStateObjects = wigStartInfo._disposeOfStateObjects; _disposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
_callToPostExecute = wigStartInfo._callToPostExecute; _callToPostExecute = wigStartInfo.CallToPostExecute;
_postExecuteWorkItemCallback = wigStartInfo._postExecuteWorkItemCallback; _postExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback;
_workItemPriority = wigStartInfo._workItemPriority; _workItemPriority = wigStartInfo.WorkItemPriority;
_startSuspended = wigStartInfo._startSuspended; _startSuspended = wigStartInfo.StartSuspended;
_fillStateWithArgs = wigStartInfo._fillStateWithArgs; _fillStateWithArgs = wigStartInfo.FillStateWithArgs;
} }
/// <summary> protected void ThrowIfReadOnly()
/// Get/Set if to use the caller's security context
/// </summary>
public virtual bool UseCallerCallContext
{
get { return _useCallerCallContext; }
set { _useCallerCallContext = value; }
}
/// <summary>
/// Get/Set if to use the caller's HTTP context
/// </summary>
public virtual bool UseCallerHttpContext
{
get { return _useCallerHttpContext; }
set { _useCallerHttpContext = value; }
}
/// <summary>
/// Get/Set if to dispose of the state object of a work item
/// </summary>
public virtual bool DisposeOfStateObjects
{
get { return _disposeOfStateObjects; }
set { _disposeOfStateObjects = value; }
}
/// <summary>
/// Get/Set the run the post execute options
/// </summary>
public virtual CallToPostExecute CallToPostExecute
{
get { return _callToPostExecute; }
set { _callToPostExecute = value; }
}
/// <summary>
/// Get/Set the default post execute callback
/// </summary>
public virtual PostExecuteWorkItemCallback PostExecuteWorkItemCallback
{
get { return _postExecuteWorkItemCallback; }
set { _postExecuteWorkItemCallback = value; }
}
/// <summary>
/// Get/Set if the work items execution should be suspended until the Start()
/// method is called.
/// </summary>
public virtual bool StartSuspended
{
get { return _startSuspended; }
set { _startSuspended = value; }
}
/// <summary>
/// Get/Set the default priority that a work item gets when it is enqueued
/// </summary>
public virtual WorkItemPriority WorkItemPriority
{ {
get { return _workItemPriority; } if (_readOnly)
set { _workItemPriority = value; } {
throw new NotSupportedException("This is a readonly instance and set is not supported");
}
} }
/// <summary> /// <summary>
/// Get/Set the if QueueWorkItem of Action<...>/Func<...> fill the /// Get/Set if to use the caller's security context
/// arguments as an object array into the state of the work item. /// </summary>
/// The arguments can be access later by IWorkItemResult.State. public virtual bool UseCallerCallContext
/// </summary> {
public virtual bool FillStateWithArgs get { return _useCallerCallContext; }
{ set
get { return _fillStateWithArgs; } {
set { _fillStateWithArgs = value; } ThrowIfReadOnly();
} _useCallerCallContext = value;
}
}
/// <summary>
/// <summary>
/// Get/Set if to use the caller's HTTP context
/// </summary>
public virtual bool UseCallerHttpContext
{
get { return _useCallerHttpContext; }
set
{
ThrowIfReadOnly();
_useCallerHttpContext = value;
}
}
/// <summary>
/// Get/Set if to dispose of the state object of a work item
/// </summary>
public virtual bool DisposeOfStateObjects
{
get { return _disposeOfStateObjects; }
set
{
ThrowIfReadOnly();
_disposeOfStateObjects = value;
}
}
/// <summary>
/// Get/Set the run the post execute options
/// </summary>
public virtual CallToPostExecute CallToPostExecute
{
get { return _callToPostExecute; }
set
{
ThrowIfReadOnly();
_callToPostExecute = value;
}
}
/// <summary>
/// Get/Set the default post execute callback
/// </summary>
public virtual PostExecuteWorkItemCallback PostExecuteWorkItemCallback
{
get { return _postExecuteWorkItemCallback; }
set
{
ThrowIfReadOnly();
_postExecuteWorkItemCallback = value;
}
}
/// <summary>
/// Get/Set if the work items execution should be suspended until the Start()
/// method is called.
/// </summary>
public virtual bool StartSuspended
{
get { return _startSuspended; }
set
{
ThrowIfReadOnly();
_startSuspended = value;
}
}
/// <summary>
/// Get/Set the default priority that a work item gets when it is enqueued
/// </summary>
public virtual WorkItemPriority WorkItemPriority
{
get { return _workItemPriority; }
set { _workItemPriority = value; }
}
/// <summary>
/// Get/Set the if QueueWorkItem of Action<...>/Func<...> fill the
/// arguments as an object array into the state of the work item.
/// The arguments can be access later by IWorkItemResult.State.
/// </summary>
public virtual bool FillStateWithArgs
{
get { return _fillStateWithArgs; }
set
{
ThrowIfReadOnly();
_fillStateWithArgs = value;
}
}
/// <summary>
/// Get a readonly version of this WIGStartInfo /// Get a readonly version of this WIGStartInfo
/// </summary> /// </summary>
/// <returns>Returns a readonly reference to this WIGStartInfoRO</returns> /// <returns>Returns a readonly reference to this WIGStartInfoRO</returns>
public WIGStartInfo AsReadOnly() public WIGStartInfo AsReadOnly()
{ {
return new WIGStartInfoRO(this); return new WIGStartInfo(this) { _readOnly = true };
} }
/*
#region WIGStartInfoRO class #region WIGStartInfoRO class
/// <summary> /// <summary>
/// A readonly version of WIGStartInfo /// A readonly version of WIGStartInfo
@@ -206,5 +258,6 @@ namespace Amib.Threading
} }
} }
#endregion #endregion
*/
} }
} }
+190
View File
@@ -0,0 +1,190 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace Amib.Threading.Internal
{
public partial class WorkItem
{
#region WorkItemResult class
private class WorkItemResult : IWorkItemResult, IInternalWorkItemResult, IInternalWaitableResult
{
/// <summary>
/// A back reference to the work item
/// </summary>
private readonly WorkItem _workItem;
public WorkItemResult(WorkItem workItem)
{
_workItem = workItem;
}
internal WorkItem GetWorkItem()
{
return _workItem;
}
#region IWorkItemResult Members
public bool IsCompleted
{
get
{
return _workItem.IsCompleted;
}
}
public bool IsCanceled
{
get
{
return _workItem.IsCanceled;
}
}
public object GetResult()
{
return _workItem.GetResult(Timeout.Infinite, true, null);
}
public object GetResult(int millisecondsTimeout, bool exitContext)
{
return _workItem.GetResult(millisecondsTimeout, exitContext, null);
}
public object GetResult(TimeSpan timeout, bool exitContext)
{
return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null);
}
public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle)
{
return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle);
}
public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle)
{
return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle);
}
public object GetResult(out Exception e)
{
return _workItem.GetResult(Timeout.Infinite, true, null, out e);
}
public object GetResult(int millisecondsTimeout, bool exitContext, out Exception e)
{
return _workItem.GetResult(millisecondsTimeout, exitContext, null, out e);
}
public object GetResult(TimeSpan timeout, bool exitContext, out Exception e)
{
return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null, out e);
}
public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
{
return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e);
}
public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
{
return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle, out e);
}
public bool Cancel()
{
return Cancel(false);
}
public bool Cancel(bool abortExecution)
{
return _workItem.Cancel(abortExecution);
}
public object State
{
get
{
return _workItem._state;
}
}
public WorkItemPriority WorkItemPriority
{
get
{
return _workItem._workItemInfo.WorkItemPriority;
}
}
/// <summary>
/// Return the result, same as GetResult()
/// </summary>
public object Result
{
get { return GetResult(); }
}
/// <summary>
/// Returns the exception if occured otherwise returns null.
/// This value is valid only after the work item completed,
/// before that it is always null.
/// </summary>
public object Exception
{
get { return _workItem._exception; }
}
#endregion
#region IInternalWorkItemResult Members
public event WorkItemStateCallback OnWorkItemStarted
{
add
{
_workItem.OnWorkItemStarted += value;
}
remove
{
_workItem.OnWorkItemStarted -= value;
}
}
public event WorkItemStateCallback OnWorkItemCompleted
{
add
{
_workItem.OnWorkItemCompleted += value;
}
remove
{
_workItem.OnWorkItemCompleted -= value;
}
}
#endregion
#region IInternalWorkItemResult Members
public IWorkItemResult GetWorkItemResult()
{
return this;
}
public IWorkItemResult<TResult> GetWorkItemResultT<TResult>()
{
return new WorkItemResultTWrapper<TResult>(this);
}
#endregion
}
#endregion
}
}
+11 -242
View File
@@ -4,68 +4,10 @@ using System.Diagnostics;
namespace Amib.Threading.Internal namespace Amib.Threading.Internal
{ {
#region WorkItem Delegate
/// <summary>
/// An internal delegate to call when the WorkItem starts or completes
/// </summary>
internal delegate void WorkItemStateCallback(WorkItem workItem);
#endregion
#region CanceledWorkItemsGroup class
public class CanceledWorkItemsGroup
{
public readonly static CanceledWorkItemsGroup NotCanceledWorkItemsGroup = new CanceledWorkItemsGroup();
private bool _isCanceled = false;
public bool IsCanceled
{
get { return _isCanceled; }
set { _isCanceled = value; }
}
}
#endregion
#region IInternalWorkItemResult interface
internal interface IInternalWorkItemResult
{
event WorkItemStateCallback OnWorkItemStarted;
event WorkItemStateCallback OnWorkItemCompleted;
}
#endregion
#region IInternalWaitableResult interface
internal interface IInternalWaitableResult
{
/// <summary>
/// This method is intent for internal use.
/// </summary>
IWorkItemResult GetWorkItemResult();
}
#endregion
#region IHasWorkItemPriority interface
public interface IHasWorkItemPriority
{
WorkItemPriority WorkItemPriority { get; }
}
#endregion
#region WorkItem class
/// <summary> /// <summary>
/// Holds a callback delegate and the state for that delegate. /// Holds a callback delegate and the state for that delegate.
/// </summary> /// </summary>
public class WorkItem : IHasWorkItemPriority public partial class WorkItem : IHasWorkItemPriority
{ {
#region WorkItemState enum #region WorkItemState enum
@@ -236,6 +178,14 @@ namespace Amib.Threading.Internal
} }
} }
internal WorkItemInfo WorkItemInfo
{
get
{
return _workItemInfo;
}
}
#endregion #endregion
#region Construction #region Construction
@@ -292,13 +242,13 @@ namespace Amib.Threading.Internal
#region Methods #region Methods
public CanceledWorkItemsGroup CanceledWorkItemsGroup internal CanceledWorkItemsGroup CanceledWorkItemsGroup
{ {
get { return _canceledWorkItemsGroup; } get { return _canceledWorkItemsGroup; }
set { _canceledWorkItemsGroup = value; } set { _canceledWorkItemsGroup = value; }
} }
public CanceledWorkItemsGroup CanceledSmartThreadPool internal CanceledWorkItemsGroup CanceledSmartThreadPool
{ {
get { return _canceledSmartThreadPool; } get { return _canceledSmartThreadPool; }
set { _canceledSmartThreadPool = value; } set { _canceledSmartThreadPool = value; }
@@ -994,186 +944,6 @@ namespace Amib.Threading.Internal
} }
} }
#region WorkItemResult class
private class WorkItemResult : IWorkItemResult, IInternalWorkItemResult, IInternalWaitableResult
{
/// <summary>
/// A back reference to the work item
/// </summary>
private readonly WorkItem _workItem;
public WorkItemResult(WorkItem workItem)
{
_workItem = workItem;
}
internal WorkItem GetWorkItem()
{
return _workItem;
}
#region IWorkItemResult Members
public bool IsCompleted
{
get
{
return _workItem.IsCompleted;
}
}
public bool IsCanceled
{
get
{
return _workItem.IsCanceled;
}
}
public object GetResult()
{
return _workItem.GetResult(Timeout.Infinite, true, null);
}
public object GetResult(int millisecondsTimeout, bool exitContext)
{
return _workItem.GetResult(millisecondsTimeout, exitContext, null);
}
public object GetResult(TimeSpan timeout, bool exitContext)
{
return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null);
}
public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle)
{
return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle);
}
public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle)
{
return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle);
}
public object GetResult(out Exception e)
{
return _workItem.GetResult(Timeout.Infinite, true, null, out e);
}
public object GetResult(int millisecondsTimeout, bool exitContext, out Exception e)
{
return _workItem.GetResult(millisecondsTimeout, exitContext, null, out e);
}
public object GetResult(TimeSpan timeout, bool exitContext, out Exception e)
{
return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null, out e);
}
public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
{
return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e);
}
public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
{
return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle, out e);
}
public bool Cancel()
{
return Cancel(false);
}
public bool Cancel(bool abortExecution)
{
return _workItem.Cancel(abortExecution);
}
public object State
{
get
{
return _workItem._state;
}
}
public WorkItemPriority WorkItemPriority
{
get
{
return _workItem._workItemInfo.WorkItemPriority;
}
}
/// <summary>
/// Return the result, same as GetResult()
/// </summary>
public object Result
{
get { return GetResult(); }
}
/// <summary>
/// Returns the exception if occured otherwise returns null.
/// This value is valid only after the work item completed,
/// before that it is always null.
/// </summary>
public object Exception
{
get { return _workItem._exception; }
}
#endregion
#region IInternalWorkItemResult Members
public event WorkItemStateCallback OnWorkItemStarted
{
add
{
_workItem.OnWorkItemStarted += value;
}
remove
{
_workItem.OnWorkItemStarted -= value;
}
}
public event WorkItemStateCallback OnWorkItemCompleted
{
add
{
_workItem.OnWorkItemCompleted += value;
}
remove
{
_workItem.OnWorkItemCompleted -= value;
}
}
#endregion
#region IInternalWorkItemResult Members
public IWorkItemResult GetWorkItemResult()
{
return this;
}
public IWorkItemResult<TResult> GetWorkItemResultT<TResult>()
{
return new WorkItemResultTWrapper<TResult>(this);
}
#endregion
}
#endregion
public void DisposeOfState() public void DisposeOfState()
{ {
if (_workItemInfo.DisposeOfStateObjects) if (_workItemInfo.DisposeOfStateObjects)
@@ -1187,5 +957,4 @@ namespace Amib.Threading.Internal
} }
} }
} }
#endregion
} }
+37 -92
View File
@@ -7,110 +7,55 @@ namespace Amib.Threading
/// </summary> /// </summary>
public class WorkItemInfo public class WorkItemInfo
{ {
/// <summary> public WorkItemInfo()
/// Use the caller's security context
/// </summary>
private bool _useCallerCallContext;
/// <summary>
/// Use the caller's security context
/// </summary>
private bool _useCallerHttpContext;
/// <summary>
/// Dispose of the state object of a work item
/// </summary>
private bool _disposeOfStateObjects;
/// <summary>
/// The option to run the post execute
/// </summary>
private CallToPostExecute _callToPostExecute;
/// <summary>
/// A post execute callback to call when none is provided in
/// the QueueWorkItem method.
/// </summary>
private PostExecuteWorkItemCallback _postExecuteWorkItemCallback;
/// <summary>
/// The priority of the work item
/// </summary>
private WorkItemPriority _workItemPriority;
public WorkItemInfo()
{ {
_useCallerCallContext = SmartThreadPool.DefaultUseCallerCallContext; UseCallerCallContext = SmartThreadPool.DefaultUseCallerCallContext;
_useCallerHttpContext = SmartThreadPool.DefaultUseCallerHttpContext; UseCallerHttpContext = SmartThreadPool.DefaultUseCallerHttpContext;
_disposeOfStateObjects = SmartThreadPool.DefaultDisposeOfStateObjects; DisposeOfStateObjects = SmartThreadPool.DefaultDisposeOfStateObjects;
_callToPostExecute = SmartThreadPool.DefaultCallToPostExecute; CallToPostExecute = SmartThreadPool.DefaultCallToPostExecute;
_postExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback; PostExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback;
_workItemPriority = SmartThreadPool.DefaultWorkItemPriority; WorkItemPriority = SmartThreadPool.DefaultWorkItemPriority;
} }
public WorkItemInfo(WorkItemInfo workItemInfo) public WorkItemInfo(WorkItemInfo workItemInfo)
{ {
_useCallerCallContext = workItemInfo._useCallerCallContext; UseCallerCallContext = workItemInfo.UseCallerCallContext;
_useCallerHttpContext = workItemInfo._useCallerHttpContext; UseCallerHttpContext = workItemInfo.UseCallerHttpContext;
_disposeOfStateObjects = workItemInfo._disposeOfStateObjects; DisposeOfStateObjects = workItemInfo.DisposeOfStateObjects;
_callToPostExecute = workItemInfo._callToPostExecute; CallToPostExecute = workItemInfo.CallToPostExecute;
_postExecuteWorkItemCallback = workItemInfo._postExecuteWorkItemCallback; PostExecuteWorkItemCallback = workItemInfo.PostExecuteWorkItemCallback;
_workItemPriority = workItemInfo._workItemPriority; WorkItemPriority = workItemInfo.WorkItemPriority;
} }
/// <summary> /// <summary>
/// Get/Set if to use the caller's security context /// Get/Set if to use the caller's security context
/// </summary> /// </summary>
public bool UseCallerCallContext public bool UseCallerCallContext { get; set; }
{
get { return _useCallerCallContext; }
set { _useCallerCallContext = value; }
}
/// <summary> /// <summary>
/// Get/Set if to use the caller's HTTP context /// Get/Set if to use the caller's HTTP context
/// </summary> /// </summary>
public bool UseCallerHttpContext public bool UseCallerHttpContext { get; set; }
{
get { return _useCallerHttpContext; }
set { _useCallerHttpContext = value; }
}
/// <summary> /// <summary>
/// Get/Set if to dispose of the state object of a work item /// Get/Set if to dispose of the state object of a work item
/// </summary> /// </summary>
public bool DisposeOfStateObjects public bool DisposeOfStateObjects { get; set; }
{
get { return _disposeOfStateObjects; }
set { _disposeOfStateObjects = value; }
}
/// <summary> /// <summary>
/// Get/Set the run the post execute options /// Get/Set the run the post execute options
/// </summary> /// </summary>
public CallToPostExecute CallToPostExecute public CallToPostExecute CallToPostExecute { get; set; }
{
get { return _callToPostExecute; }
set { _callToPostExecute = value; }
}
/// <summary> /// <summary>
/// Get/Set the post execute callback /// Get/Set the post execute callback
/// </summary> /// </summary>
public PostExecuteWorkItemCallback PostExecuteWorkItemCallback public PostExecuteWorkItemCallback PostExecuteWorkItemCallback { get; set; }
{
get { return _postExecuteWorkItemCallback; }
set { _postExecuteWorkItemCallback = value; }
}
/// <summary> /// <summary>
/// Get/Set the work items priority /// Get/Set the work items priority
/// </summary> /// </summary>
public WorkItemPriority WorkItemPriority public WorkItemPriority WorkItemPriority { get; set; }
{
get { return _workItemPriority; }
set { _workItemPriority = value; }
}
} }
#endregion #endregion
+18 -23
View File
@@ -13,11 +13,10 @@ namespace Amib.Threading.Internal
/// </summary> /// </summary>
private string _name = "WorkItemsGroupBase"; private string _name = "WorkItemsGroupBase";
/// <summary> public WorkItemsGroupBase()
/// Inidcates if the SmartThreadPool/WorkItemsGroup is idle. {
/// Its value is true if the _isIdleWaitHandle is set. IsIdle = true;
/// </summary> }
private bool _isIdle = true;
#endregion #endregion
@@ -82,11 +81,7 @@ namespace Amib.Threading.Internal
/// <summary> /// <summary>
/// IsIdle is true when there are no work items running or queued. /// IsIdle is true when there are no work items running or queued.
/// </summary> /// </summary>
public bool IsIdle public bool IsIdle { get; protected set; }
{
get { return _isIdle; }
protected set { _isIdle = value; }
}
#endregion #endregion
@@ -302,11 +297,11 @@ namespace Amib.Threading.Internal
WorkItem workItem = WorkItemFactory.CreateWorkItem( WorkItem workItem = WorkItemFactory.CreateWorkItem(
this, this,
WIGStartInfo, WIGStartInfo,
delegate state =>
{ {
action.Invoke(arg); action.Invoke(arg);
return null; return null;
}, },
WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null); WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null);
Enqueue(workItem); Enqueue(workItem);
return workItem.GetWorkItemResult(); return workItem.GetWorkItemResult();
@@ -318,7 +313,7 @@ namespace Amib.Threading.Internal
WorkItem workItem = WorkItemFactory.CreateWorkItem( WorkItem workItem = WorkItemFactory.CreateWorkItem(
this, this,
WIGStartInfo, WIGStartInfo,
delegate state =>
{ {
action.Invoke(arg1, arg2); action.Invoke(arg1, arg2);
return null; return null;
@@ -334,7 +329,7 @@ namespace Amib.Threading.Internal
WorkItem workItem = WorkItemFactory.CreateWorkItem( WorkItem workItem = WorkItemFactory.CreateWorkItem(
this, this,
WIGStartInfo, WIGStartInfo,
delegate state =>
{ {
action.Invoke(arg1, arg2, arg3); action.Invoke(arg1, arg2, arg3);
return null; return null;
@@ -351,7 +346,7 @@ namespace Amib.Threading.Internal
WorkItem workItem = WorkItemFactory.CreateWorkItem( WorkItem workItem = WorkItemFactory.CreateWorkItem(
this, this,
WIGStartInfo, WIGStartInfo,
delegate state =>
{ {
action.Invoke(arg1, arg2, arg3, arg4); action.Invoke(arg1, arg2, arg3, arg4);
return null; return null;
@@ -371,7 +366,7 @@ namespace Amib.Threading.Internal
WorkItem workItem = WorkItemFactory.CreateWorkItem( WorkItem workItem = WorkItemFactory.CreateWorkItem(
this, this,
WIGStartInfo, WIGStartInfo,
delegate state =>
{ {
return func.Invoke(); return func.Invoke();
}); });
@@ -385,7 +380,7 @@ namespace Amib.Threading.Internal
WorkItem workItem = WorkItemFactory.CreateWorkItem( WorkItem workItem = WorkItemFactory.CreateWorkItem(
this, this,
WIGStartInfo, WIGStartInfo,
delegate state =>
{ {
return func.Invoke(arg); return func.Invoke(arg);
}, },
@@ -400,7 +395,7 @@ namespace Amib.Threading.Internal
WorkItem workItem = WorkItemFactory.CreateWorkItem( WorkItem workItem = WorkItemFactory.CreateWorkItem(
this, this,
WIGStartInfo, WIGStartInfo,
delegate state =>
{ {
return func.Invoke(arg1, arg2); return func.Invoke(arg1, arg2);
}, },
@@ -416,7 +411,7 @@ namespace Amib.Threading.Internal
WorkItem workItem = WorkItemFactory.CreateWorkItem( WorkItem workItem = WorkItemFactory.CreateWorkItem(
this, this,
WIGStartInfo, WIGStartInfo,
delegate state =>
{ {
return func.Invoke(arg1, arg2, arg3); return func.Invoke(arg1, arg2, arg3);
}, },
@@ -432,7 +427,7 @@ namespace Amib.Threading.Internal
WorkItem workItem = WorkItemFactory.CreateWorkItem( WorkItem workItem = WorkItemFactory.CreateWorkItem(
this, this,
WIGStartInfo, WIGStartInfo,
delegate state =>
{ {
return func.Invoke(arg1, arg2, arg3, arg4); return func.Invoke(arg1, arg2, arg3, arg4);
}, },
-44
View File
@@ -1,11 +1,5 @@
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly: AssemblyTitle("")] [assembly: AssemblyTitle("")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
@@ -14,45 +8,7 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyCopyright("")] [assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.*")]
//
// In order to sign your assembly you must specify a key to use. Refer to the
// Microsoft .NET Framework documentation for more information on assembly signing.
//
// Use the attributes below to control which key is used for signing.
//
// Notes:
// (*) If no key is specified, the assembly is not signed.
// (*) KeyName refers to a key that has been installed in the Crypto Service
// Provider (CSP) on your machine. KeyFile refers to a file which contains
// a key.
// (*) If the KeyFile and the KeyName values are both specified, the
// following processing occurs:
// (1) If the KeyName can be found in the CSP, that key is used.
// (2) If the KeyName does not exist and the KeyFile does exist, the key
// in the KeyFile is installed into the CSP and used.
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
// When specifying the KeyFile, the location of the KeyFile should be
// relative to the project output directory which is
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
// located in the project directory, you would specify the AssemblyKeyFile
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
// documentation for more information on this.
//
[assembly: AssemblyDelaySign(false)] [assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")] [assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")] [assembly: AssemblyKeyName("")]
-44
View File
@@ -1,11 +1,5 @@
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly: AssemblyTitle("")] [assembly: AssemblyTitle("")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
@@ -14,45 +8,7 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyCopyright("")] [assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.*")]
//
// In order to sign your assembly you must specify a key to use. Refer to the
// Microsoft .NET Framework documentation for more information on assembly signing.
//
// Use the attributes below to control which key is used for signing.
//
// Notes:
// (*) If no key is specified, the assembly is not signed.
// (*) KeyName refers to a key that has been installed in the Crypto Service
// Provider (CSP) on your machine. KeyFile refers to a file which contains
// a key.
// (*) If the KeyFile and the KeyName values are both specified, the
// following processing occurs:
// (1) If the KeyName can be found in the CSP, that key is used.
// (2) If the KeyName does not exist and the KeyFile does exist, the key
// in the KeyFile is installed into the CSP and used.
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
// When specifying the KeyFile, the location of the KeyFile should be
// relative to the project output directory which is
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
// located in the project directory, you would specify the AssemblyKeyFile
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
// documentation for more information on this.
//
[assembly: AssemblyDelaySign(false)] [assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")] [assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")] [assembly: AssemblyKeyName("")]
+16 -23
View File
@@ -1,14 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Diagnostics;
using System.Reflection;
using System.Drawing.Imaging;
namespace UsageControl namespace UsageControl
@@ -40,9 +34,8 @@ namespace UsageControl
{ {
//Debug.WriteLine("GenerateItemImage"); //Debug.WriteLine("GenerateItemImage");
Bitmap itemImage = null;
Rectangle rc = new Rectangle(0, 0, width, height); Rectangle rc = new Rectangle(0, 0, width, height);
itemImage = new Bitmap(rc.Width, rc.Height); Bitmap itemImage = new Bitmap(rc.Width, rc.Height);
/// Create button /// Create button
rc.Inflate(-3, -3); rc.Inflate(-3, -3);
@@ -90,11 +83,11 @@ namespace UsageControl
{ {
//Debug.WriteLine("GetItemsImage"); //Debug.WriteLine("GetItemsImage");
Bitmap itemImage = null; Bitmap itemImage;
if (!_imagesCache.ContainsKey(color)) if (!_imagesCache.ContainsKey(color))
{ {
Rectangle rc = new Rectangle(0, 0, this.Width, _itemHeight); Rectangle rc = new Rectangle(0, 0, Width, _itemHeight);
itemImage = new Bitmap(rc.Width, rc.Height); itemImage = new Bitmap(rc.Width, rc.Height);
/// Create button /// Create button
@@ -120,7 +113,7 @@ namespace UsageControl
GraphicsPath path3 = GetPath(rc3, rc3.Height); GraphicsPath path3 = GetPath(rc3, rc3.Height);
LinearGradientBrush br3 = new LinearGradientBrush(rc3, Color.FromArgb(255, Color.White), Color.FromArgb(0, Color.White), LinearGradientMode.Vertical); LinearGradientBrush br3 = new LinearGradientBrush(rc3, Color.FromArgb(255, Color.White), Color.FromArgb(0, Color.White), LinearGradientMode.Vertical);
itemImage = new Bitmap(this.Width - 2, _itemHeight); itemImage = new Bitmap(Width - 2, _itemHeight);
Graphics g = Graphics.FromImage(itemImage); Graphics g = Graphics.FromImage(itemImage);
g.SmoothingMode = SmoothingMode.AntiAlias; g.SmoothingMode = SmoothingMode.AntiAlias;
g.FillPath(br2, path2); g.FillPath(br2, path2);
@@ -140,12 +133,12 @@ namespace UsageControl
//Debug.WriteLine("EnableDoubleBuffering"); //Debug.WriteLine("EnableDoubleBuffering");
// Set the value of the double-buffering style bits to true. // Set the value of the double-buffering style bits to true.
this.SetStyle(ControlStyles.DoubleBuffer | SetStyle(ControlStyles.DoubleBuffer |
ControlStyles.UserPaint | ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint | ControlStyles.AllPaintingInWmPaint |
ControlStyles.SupportsTransparentBackColor, ControlStyles.SupportsTransparentBackColor,
true); true);
this.UpdateStyles(); UpdateStyles();
} }
public void Reset() public void Reset()
@@ -245,7 +238,7 @@ namespace UsageControl
text = "(" + (_queuedItems.Count - _maxItemsVisible) + ")..."; text = "(" + (_queuedItems.Count - _maxItemsVisible) + ")...";
} }
SizeF size = g.MeasureString(entry.Text, this.Font); SizeF size = g.MeasureString(entry.Text, Font);
//Debug.WriteLine(size.Width); //Debug.WriteLine(size.Width);
Bitmap itemImage = GetItemsImage(entry.Color); Bitmap itemImage = GetItemsImage(entry.Color);
@@ -256,7 +249,7 @@ namespace UsageControl
g.DrawImage(itemImage, -1, slot.Top-2); g.DrawImage(itemImage, -1, slot.Top-2);
//g.DrawString(text, this.Font, Brushes.Black, new RectangleF((this.Width - size.Width) / 2, top + 2, this.Width, bottom)); //g.DrawString(text, this.Font, Brushes.Black, new RectangleF((this.Width - size.Width) / 2, top + 2, this.Width, bottom));
g.DrawString(text, this.Font, Brushes.Black, slot); g.DrawString(text, Font, Brushes.Black, slot);
++i; ++i;
} }
@@ -282,15 +275,15 @@ namespace UsageControl
private void ControlRezised() private void ControlRezised()
{ {
//Debug.WriteLine("ControlRezised"); //Debug.WriteLine("ControlRezised");
Graphics g = Graphics.FromHwnd(this.Handle); Graphics g = Graphics.FromHwnd(Handle);
SizeF size = g.MeasureString("X", this.Font); SizeF size = g.MeasureString("X", Font);
g.Dispose(); g.Dispose();
_itemHeight = (int)size.Height + 5; _itemHeight = (int)size.Height + 5;
_maxItemsVisible = this.Height / _itemHeight - 1; _maxItemsVisible = Height / _itemHeight - 1;
_lastVisibleItemIndex = _maxItemsVisible; _lastVisibleItemIndex = _maxItemsVisible;
_imagesCache = new Dictionary<Color, Bitmap>(); _imagesCache = new Dictionary<Color, Bitmap>();
Rectangle border = new Rectangle(0, 0, this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1); Rectangle border = new Rectangle(0, 0, ClientRectangle.Width - 1, ClientRectangle.Height - 1);
_pathBorder = GetPath(border, 20); _pathBorder = GetPath(border, 20);
PrepareSlots(); PrepareSlots();
@@ -303,8 +296,8 @@ namespace UsageControl
_slots = new RectangleF[_maxItemsVisible+5]; _slots = new RectangleF[_maxItemsVisible+5];
for (int i = 0; i < _slots.Length; i++) for (int i = 0; i < _slots.Length; i++)
{ {
int top = 0; int top;
int bottom = 0; int bottom;
if (topdown) if (topdown)
{ {
bottom = 1; bottom = 1;
@@ -314,13 +307,13 @@ namespace UsageControl
} }
else else
{ {
bottom = this.Height - 1; bottom = Height - 1;
top = bottom; top = bottom;
bottom -= i * _itemHeight; bottom -= i * _itemHeight;
top -= (i + 1) * _itemHeight; top -= (i + 1) * _itemHeight;
} }
_slots[i] = new RectangleF((this.Width - 55) / 2, top + 2, this.Width, bottom); _slots[i] = new RectangleF((Width - 55) / 2, top + 2, Width, bottom);
} }
} }
+6 -23
View File
@@ -1,6 +1,3 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing; using System.Drawing;
namespace UsageControl namespace UsageControl
@@ -9,10 +6,6 @@ namespace UsageControl
{ {
public class QueueUsageEntry public class QueueUsageEntry
{ {
private string _text;
private Color _color;
private bool _isExecuting;
public QueueUsageEntry( public QueueUsageEntry(
string text, string text,
Color color) : this (text, color, false) Color color) : this (text, color, false)
@@ -24,26 +17,16 @@ namespace UsageControl
Color color, Color color,
bool blink) bool blink)
{ {
_text = text; Text = text;
_color = color; Color = color;
_isExecuting = blink; IsExecuting = blink;
} }
public Color Color public Color Color { get; private set; }
{
get { return _color; }
}
public string Text public string Text { get; private set; }
{
get { return _text; }
}
public bool IsExecuting public bool IsExecuting { get; set; }
{
get { return _isExecuting; }
set { _isExecuting = value; }
}
} }
} }
} }
+6 -8
View File
@@ -1,8 +1,6 @@
using System; using System;
using System.Collections;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.Data;
using System.Windows.Forms; using System.Windows.Forms;
namespace UsageControl namespace UsageControl
@@ -10,12 +8,12 @@ namespace UsageControl
/// <summary> /// <summary>
/// Summary description for UsageHistoryControl. /// Summary description for UsageHistoryControl.
/// </summary> /// </summary>
public class UsageHistoryControl : System.Windows.Forms.UserControl public class UsageHistoryControl : UserControl
{ {
/// <summary> /// <summary>
/// Required designer variable. /// Required designer variable.
/// </summary> /// </summary>
private System.ComponentModel.Container components = null; private Container components = null;
private const int squareWidth = 12; private const int squareWidth = 12;
private const int maxLastValuesCount = 2000; private const int maxLastValuesCount = 2000;
@@ -83,17 +81,17 @@ namespace UsageControl
private void EnableDoubleBuffering() private void EnableDoubleBuffering()
{ {
// Set the value of the double-buffering style bits to true. // Set the value of the double-buffering style bits to true.
this.SetStyle(ControlStyles.DoubleBuffer | SetStyle(ControlStyles.DoubleBuffer |
ControlStyles.UserPaint | ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint, ControlStyles.AllPaintingInWmPaint,
true); true);
this.UpdateStyles(); UpdateStyles();
} }
protected override void OnResize(EventArgs e) protected override void OnResize(EventArgs e)
{ {
// Invalidate the control to get a repaint. // Invalidate the control to get a repaint.
this.Invalidate(); Invalidate();
} }
protected override void OnPaint(PaintEventArgs e) protected override void OnPaint(PaintEventArgs e)
@@ -183,7 +181,7 @@ namespace UsageControl
max = value; max = value;
// Invalidate the control to get a repaint. // Invalidate the control to get a repaint.
this.Invalidate(); Invalidate();
} }
} }
+1 -4
View File
@@ -1,9 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing; using System.Drawing;
using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using UsageControl; using UsageControl;
using Amib.Threading; using Amib.Threading;
@@ -180,7 +177,7 @@ namespace WorkItemsGroupDemo
{ {
lblStatus6.Text = _stp.IsIdle ? "Idle" : "Working"; lblStatus6.Text = _stp.IsIdle ? "Idle" : "Working";
object [] statesWorking = null; object[] statesWorking;
lock (_workingStates.SyncRoot) lock (_workingStates.SyncRoot)
{ {
statesWorking = new object[_workingStates.Count]; statesWorking = new object[_workingStates.Count];
-1
View File
@@ -1,5 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Windows.Forms; using System.Windows.Forms;
namespace WorkItemsGroupDemo namespace WorkItemsGroupDemo
@@ -1,10 +1,6 @@
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("WindowsApplication1")] [assembly: AssemblyTitle("WindowsApplication1")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
@@ -13,21 +9,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCopyright("Copyright © 2006")] [assembly: AssemblyCopyright("Copyright © 2006")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("68872ba4-6524-406b-9c96-cf8ca3f4c729")] [assembly: Guid("68872ba4-6524-406b-9c96-cf8ca3f4c729")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")]