aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2013-05-01 23:00:46 +0100
committerJustin Clark-Casey (justincc)2013-05-01 23:00:46 +0100
commit854dcd1abddc3eef33da953592deb61133e5e7ed (patch)
treed89d9d616384fdb4e6b4eec658339eac2f079ff2
parentAdd in-code exaplanation for the change in cancellation signalling in STP 2.2... (diff)
downloadopensim-SC-854dcd1abddc3eef33da953592deb61133e5e7ed.zip
opensim-SC-854dcd1abddc3eef33da953592deb61133e5e7ed.tar.gz
opensim-SC-854dcd1abddc3eef33da953592deb61133e5e7ed.tar.bz2
opensim-SC-854dcd1abddc3eef33da953592deb61133e5e7ed.tar.xz
Fix SmartThreadPool line endings in recent update from dos to unix
Diffstat (limited to '')
-rw-r--r--ThirdParty/SmartThreadPool/CallerThreadContext.cs276
-rw-r--r--ThirdParty/SmartThreadPool/CanceledWorkItemsGroup.cs26
-rw-r--r--ThirdParty/SmartThreadPool/EventWaitHandle.cs206
-rw-r--r--ThirdParty/SmartThreadPool/EventWaitHandleFactory.cs164
-rw-r--r--ThirdParty/SmartThreadPool/Exceptions.cs222
-rw-r--r--ThirdParty/SmartThreadPool/Interfaces.cs1256
-rw-r--r--ThirdParty/SmartThreadPool/InternalInterfaces.cs54
-rw-r--r--ThirdParty/SmartThreadPool/PriorityQueue.cs478
-rw-r--r--ThirdParty/SmartThreadPool/Properties/AssemblyInfo.cs46
-rw-r--r--ThirdParty/SmartThreadPool/SLExt.cs32
-rw-r--r--ThirdParty/SmartThreadPool/STPEventWaitHandle.cs122
-rw-r--r--ThirdParty/SmartThreadPool/STPPerformanceCounter.cs896
-rw-r--r--ThirdParty/SmartThreadPool/STPStartInfo.cs424
-rw-r--r--ThirdParty/SmartThreadPool/SmartThreadPool.ThreadEntry.cs118
-rw-r--r--ThirdParty/SmartThreadPool/SmartThreadPool.cs3464
-rw-r--r--ThirdParty/SmartThreadPool/SynchronizedDictionary.cs178
-rw-r--r--ThirdParty/SmartThreadPool/WIGStartInfo.cs342
-rw-r--r--ThirdParty/SmartThreadPool/WorkItem.WorkItemResult.cs380
-rw-r--r--ThirdParty/SmartThreadPool/WorkItemFactory.cs686
-rw-r--r--ThirdParty/SmartThreadPool/WorkItemInfo.cs138
-rw-r--r--ThirdParty/SmartThreadPool/WorkItemResultTWrapper.cs256
-rw-r--r--ThirdParty/SmartThreadPool/WorkItemsGroup.cs722
-rw-r--r--ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs940
-rw-r--r--ThirdParty/SmartThreadPool/WorkItemsQueue.cs1290
24 files changed, 6358 insertions, 6358 deletions
diff --git a/ThirdParty/SmartThreadPool/CallerThreadContext.cs b/ThirdParty/SmartThreadPool/CallerThreadContext.cs
index 2177241..e63add5 100644
--- a/ThirdParty/SmartThreadPool/CallerThreadContext.cs
+++ b/ThirdParty/SmartThreadPool/CallerThreadContext.cs
@@ -1,138 +1,138 @@
1 1
2#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE) 2#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
3 3
4using System; 4using System;
5using System.Diagnostics; 5using System.Diagnostics;
6using System.Threading; 6using System.Threading;
7using System.Reflection; 7using System.Reflection;
8using System.Web; 8using System.Web;
9using System.Runtime.Remoting.Messaging; 9using System.Runtime.Remoting.Messaging;
10 10
11 11
12namespace Amib.Threading.Internal 12namespace Amib.Threading.Internal
13{ 13{
14#region CallerThreadContext class 14#region CallerThreadContext class
15 15
16 /// <summary> 16 /// <summary>
17 /// This class stores the caller call context in order to restore 17 /// This class stores the caller call context in order to restore
18 /// it when the work item is executed in the thread pool environment. 18 /// it when the work item is executed in the thread pool environment.
19 /// </summary> 19 /// </summary>
20 internal class CallerThreadContext 20 internal class CallerThreadContext
21 { 21 {
22#region Prepare reflection information 22#region Prepare reflection information
23 23
24 // Cached type information. 24 // Cached type information.
25 private static readonly MethodInfo getLogicalCallContextMethodInfo = 25 private static readonly MethodInfo getLogicalCallContextMethodInfo =
26 typeof(Thread).GetMethod("GetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic); 26 typeof(Thread).GetMethod("GetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic);
27 27
28 private static readonly MethodInfo setLogicalCallContextMethodInfo = 28 private static readonly MethodInfo setLogicalCallContextMethodInfo =
29 typeof(Thread).GetMethod("SetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic); 29 typeof(Thread).GetMethod("SetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic);
30 30
31 private static string HttpContextSlotName = GetHttpContextSlotName(); 31 private static string HttpContextSlotName = GetHttpContextSlotName();
32 32
33 private static string GetHttpContextSlotName() 33 private static string GetHttpContextSlotName()
34 { 34 {
35 FieldInfo fi = typeof(HttpContext).GetField("CallContextSlotName", BindingFlags.Static | BindingFlags.NonPublic); 35 FieldInfo fi = typeof(HttpContext).GetField("CallContextSlotName", BindingFlags.Static | BindingFlags.NonPublic);
36 36
37 if (fi != null) 37 if (fi != null)
38 { 38 {
39 return (string) fi.GetValue(null); 39 return (string) fi.GetValue(null);
40 } 40 }
41 41
42 return "HttpContext"; 42 return "HttpContext";
43 } 43 }
44 44
45 #endregion 45 #endregion
46 46
47#region Private fields 47#region Private fields
48 48
49 private HttpContext _httpContext; 49 private HttpContext _httpContext;
50 private LogicalCallContext _callContext; 50 private LogicalCallContext _callContext;
51 51
52 #endregion 52 #endregion
53 53
54 /// <summary> 54 /// <summary>
55 /// Constructor 55 /// Constructor
56 /// </summary> 56 /// </summary>
57 private CallerThreadContext() 57 private CallerThreadContext()
58 { 58 {
59 } 59 }
60 60
61 public bool CapturedCallContext 61 public bool CapturedCallContext
62 { 62 {
63 get 63 get
64 { 64 {
65 return (null != _callContext); 65 return (null != _callContext);
66 } 66 }
67 } 67 }
68 68
69 public bool CapturedHttpContext 69 public bool CapturedHttpContext
70 { 70 {
71 get 71 get
72 { 72 {
73 return (null != _httpContext); 73 return (null != _httpContext);
74 } 74 }
75 } 75 }
76 76
77 /// <summary> 77 /// <summary>
78 /// Captures the current thread context 78 /// Captures the current thread context
79 /// </summary> 79 /// </summary>
80 /// <returns></returns> 80 /// <returns></returns>
81 public static CallerThreadContext Capture( 81 public static CallerThreadContext Capture(
82 bool captureCallContext, 82 bool captureCallContext,
83 bool captureHttpContext) 83 bool captureHttpContext)
84 { 84 {
85 Debug.Assert(captureCallContext || captureHttpContext); 85 Debug.Assert(captureCallContext || captureHttpContext);
86 86
87 CallerThreadContext callerThreadContext = new CallerThreadContext(); 87 CallerThreadContext callerThreadContext = new CallerThreadContext();
88 88
89 // TODO: In NET 2.0, redo using the new feature of ExecutionContext class - Capture() 89 // TODO: In NET 2.0, redo using the new feature of ExecutionContext class - Capture()
90 // Capture Call Context 90 // Capture Call Context
91 if(captureCallContext && (getLogicalCallContextMethodInfo != null)) 91 if(captureCallContext && (getLogicalCallContextMethodInfo != null))
92 { 92 {
93 callerThreadContext._callContext = (LogicalCallContext)getLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, null); 93 callerThreadContext._callContext = (LogicalCallContext)getLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, null);
94 if (callerThreadContext._callContext != null) 94 if (callerThreadContext._callContext != null)
95 { 95 {
96 callerThreadContext._callContext = (LogicalCallContext)callerThreadContext._callContext.Clone(); 96 callerThreadContext._callContext = (LogicalCallContext)callerThreadContext._callContext.Clone();
97 } 97 }
98 } 98 }
99 99
100 // Capture httpContext 100 // Capture httpContext
101 if (captureHttpContext && (null != HttpContext.Current)) 101 if (captureHttpContext && (null != HttpContext.Current))
102 { 102 {
103 callerThreadContext._httpContext = HttpContext.Current; 103 callerThreadContext._httpContext = HttpContext.Current;
104 } 104 }
105 105
106 return callerThreadContext; 106 return callerThreadContext;
107 } 107 }
108 108
109 /// <summary> 109 /// <summary>
110 /// Applies the thread context stored earlier 110 /// Applies the thread context stored earlier
111 /// </summary> 111 /// </summary>
112 /// <param name="callerThreadContext"></param> 112 /// <param name="callerThreadContext"></param>
113 public static void Apply(CallerThreadContext callerThreadContext) 113 public static void Apply(CallerThreadContext callerThreadContext)
114 { 114 {
115 if (null == callerThreadContext) 115 if (null == callerThreadContext)
116 { 116 {
117 throw new ArgumentNullException("callerThreadContext"); 117 throw new ArgumentNullException("callerThreadContext");
118 } 118 }
119 119
120 // Todo: In NET 2.0, redo using the new feature of ExecutionContext class - Run() 120 // Todo: In NET 2.0, redo using the new feature of ExecutionContext class - Run()
121 // Restore call context 121 // Restore call context
122 if ((callerThreadContext._callContext != null) && (setLogicalCallContextMethodInfo != null)) 122 if ((callerThreadContext._callContext != null) && (setLogicalCallContextMethodInfo != null))
123 { 123 {
124 setLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, new object[] { callerThreadContext._callContext }); 124 setLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, new object[] { callerThreadContext._callContext });
125 } 125 }
126 126
127 // Restore HttpContext 127 // Restore HttpContext
128 if (callerThreadContext._httpContext != null) 128 if (callerThreadContext._httpContext != null)
129 { 129 {
130 HttpContext.Current = callerThreadContext._httpContext; 130 HttpContext.Current = callerThreadContext._httpContext;
131 //CallContext.SetData(HttpContextSlotName, callerThreadContext._httpContext); 131 //CallContext.SetData(HttpContextSlotName, callerThreadContext._httpContext);
132 } 132 }
133 } 133 }
134 } 134 }
135 135
136 #endregion 136 #endregion
137} 137}
138#endif 138#endif
diff --git a/ThirdParty/SmartThreadPool/CanceledWorkItemsGroup.cs b/ThirdParty/SmartThreadPool/CanceledWorkItemsGroup.cs
index 4a2a3e7..5752957 100644
--- a/ThirdParty/SmartThreadPool/CanceledWorkItemsGroup.cs
+++ b/ThirdParty/SmartThreadPool/CanceledWorkItemsGroup.cs
@@ -1,14 +1,14 @@
1namespace Amib.Threading.Internal 1namespace Amib.Threading.Internal
2{ 2{
3 internal class CanceledWorkItemsGroup 3 internal class CanceledWorkItemsGroup
4 { 4 {
5 public readonly static CanceledWorkItemsGroup NotCanceledWorkItemsGroup = new CanceledWorkItemsGroup(); 5 public readonly static CanceledWorkItemsGroup NotCanceledWorkItemsGroup = new CanceledWorkItemsGroup();
6 6
7 public CanceledWorkItemsGroup() 7 public CanceledWorkItemsGroup()
8 { 8 {
9 IsCanceled = false; 9 IsCanceled = false;
10 } 10 }
11 11
12 public bool IsCanceled { get; set; } 12 public bool IsCanceled { get; set; }
13 } 13 }
14} \ No newline at end of file 14} \ No newline at end of file
diff --git a/ThirdParty/SmartThreadPool/EventWaitHandle.cs b/ThirdParty/SmartThreadPool/EventWaitHandle.cs
index 70a1a29..25be07a 100644
--- a/ThirdParty/SmartThreadPool/EventWaitHandle.cs
+++ b/ThirdParty/SmartThreadPool/EventWaitHandle.cs
@@ -1,104 +1,104 @@
1#if (_WINDOWS_CE) 1#if (_WINDOWS_CE)
2 2
3using System; 3using System;
4using System.Runtime.InteropServices; 4using System.Runtime.InteropServices;
5using System.Threading; 5using System.Threading;
6 6
7namespace Amib.Threading.Internal 7namespace Amib.Threading.Internal
8{ 8{
9 /// <summary> 9 /// <summary>
10 /// EventWaitHandle class 10 /// EventWaitHandle class
11 /// In WindowsCE this class doesn't exist and I needed the WaitAll and WaitAny implementation. 11 /// In WindowsCE this class doesn't exist and I needed the WaitAll and WaitAny implementation.
12 /// So I wrote this class to implement these two methods with some of their overloads. 12 /// So I wrote this class to implement these two methods with some of their overloads.
13 /// It uses the WaitForMultipleObjects API to do the WaitAll and WaitAny. 13 /// It uses the WaitForMultipleObjects API to do the WaitAll and WaitAny.
14 /// Note that this class doesn't even inherit from WaitHandle! 14 /// Note that this class doesn't even inherit from WaitHandle!
15 /// </summary> 15 /// </summary>
16 public class STPEventWaitHandle 16 public class STPEventWaitHandle
17 { 17 {
18 #region Public Constants 18 #region Public Constants
19 19
20 public const int WaitTimeout = Timeout.Infinite; 20 public const int WaitTimeout = Timeout.Infinite;
21 21
22 #endregion 22 #endregion
23 23
24 #region Private External Constants 24 #region Private External Constants
25 25
26 private const Int32 WAIT_FAILED = -1; 26 private const Int32 WAIT_FAILED = -1;
27 private const Int32 WAIT_TIMEOUT = 0x102; 27 private const Int32 WAIT_TIMEOUT = 0x102;
28 private const UInt32 INFINITE = 0xFFFFFFFF; 28 private const UInt32 INFINITE = 0xFFFFFFFF;
29 29
30 #endregion 30 #endregion
31 31
32 #region WaitAll and WaitAny 32 #region WaitAll and WaitAny
33 33
34 internal static bool WaitOne(WaitHandle waitHandle, int millisecondsTimeout, bool exitContext) 34 internal static bool WaitOne(WaitHandle waitHandle, int millisecondsTimeout, bool exitContext)
35 { 35 {
36 return waitHandle.WaitOne(millisecondsTimeout, exitContext); 36 return waitHandle.WaitOne(millisecondsTimeout, exitContext);
37 } 37 }
38 38
39 private static IntPtr[] PrepareNativeHandles(WaitHandle[] waitHandles) 39 private static IntPtr[] PrepareNativeHandles(WaitHandle[] waitHandles)
40 { 40 {
41 IntPtr[] nativeHandles = new IntPtr[waitHandles.Length]; 41 IntPtr[] nativeHandles = new IntPtr[waitHandles.Length];
42 for (int i = 0; i < waitHandles.Length; i++) 42 for (int i = 0; i < waitHandles.Length; i++)
43 { 43 {
44 nativeHandles[i] = waitHandles[i].Handle; 44 nativeHandles[i] = waitHandles[i].Handle;
45 } 45 }
46 return nativeHandles; 46 return nativeHandles;
47 } 47 }
48 48
49 public static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext) 49 public static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
50 { 50 {
51 uint timeout = millisecondsTimeout < 0 ? INFINITE : (uint)millisecondsTimeout; 51 uint timeout = millisecondsTimeout < 0 ? INFINITE : (uint)millisecondsTimeout;
52 52
53 IntPtr[] nativeHandles = PrepareNativeHandles(waitHandles); 53 IntPtr[] nativeHandles = PrepareNativeHandles(waitHandles);
54 54
55 int result = WaitForMultipleObjects((uint)waitHandles.Length, nativeHandles, true, timeout); 55 int result = WaitForMultipleObjects((uint)waitHandles.Length, nativeHandles, true, timeout);
56 56
57 if (result == WAIT_TIMEOUT || result == WAIT_FAILED) 57 if (result == WAIT_TIMEOUT || result == WAIT_FAILED)
58 { 58 {
59 return false; 59 return false;
60 } 60 }
61 61
62 return true; 62 return true;
63 } 63 }
64 64
65 65
66 public static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext) 66 public static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
67 { 67 {
68 uint timeout = millisecondsTimeout < 0 ? INFINITE : (uint)millisecondsTimeout; 68 uint timeout = millisecondsTimeout < 0 ? INFINITE : (uint)millisecondsTimeout;
69 69
70 IntPtr[] nativeHandles = PrepareNativeHandles(waitHandles); 70 IntPtr[] nativeHandles = PrepareNativeHandles(waitHandles);
71 71
72 int result = WaitForMultipleObjects((uint)waitHandles.Length, nativeHandles, false, timeout); 72 int result = WaitForMultipleObjects((uint)waitHandles.Length, nativeHandles, false, timeout);
73 73
74 if (result >= 0 && result < waitHandles.Length) 74 if (result >= 0 && result < waitHandles.Length)
75 { 75 {
76 return result; 76 return result;
77 } 77 }
78 78
79 return -1; 79 return -1;
80 } 80 }
81 81
82 public static int WaitAny(WaitHandle[] waitHandles) 82 public static int WaitAny(WaitHandle[] waitHandles)
83 { 83 {
84 return WaitAny(waitHandles, Timeout.Infinite, false); 84 return WaitAny(waitHandles, Timeout.Infinite, false);
85 } 85 }
86 86
87 public static int WaitAny(WaitHandle[] waitHandles, TimeSpan timeout, bool exitContext) 87 public static int WaitAny(WaitHandle[] waitHandles, TimeSpan timeout, bool exitContext)
88 { 88 {
89 int millisecondsTimeout = (int)timeout.TotalMilliseconds; 89 int millisecondsTimeout = (int)timeout.TotalMilliseconds;
90 90
91 return WaitAny(waitHandles, millisecondsTimeout, false); 91 return WaitAny(waitHandles, millisecondsTimeout, false);
92 } 92 }
93 93
94 #endregion 94 #endregion
95 95
96 #region External methods 96 #region External methods
97 97
98 [DllImport("coredll.dll", SetLastError = true)] 98 [DllImport("coredll.dll", SetLastError = true)]
99 public static extern int WaitForMultipleObjects(uint nCount, IntPtr[] lpHandles, bool fWaitAll, uint dwMilliseconds); 99 public static extern int WaitForMultipleObjects(uint nCount, IntPtr[] lpHandles, bool fWaitAll, uint dwMilliseconds);
100 100
101 #endregion 101 #endregion
102 } 102 }
103} 103}
104#endif \ No newline at end of file 104#endif \ No newline at end of file
diff --git a/ThirdParty/SmartThreadPool/EventWaitHandleFactory.cs b/ThirdParty/SmartThreadPool/EventWaitHandleFactory.cs
index 2f8c55b..3c9c849 100644
--- a/ThirdParty/SmartThreadPool/EventWaitHandleFactory.cs
+++ b/ThirdParty/SmartThreadPool/EventWaitHandleFactory.cs
@@ -1,82 +1,82 @@
1using System.Threading; 1using System.Threading;
2 2
3#if (_WINDOWS_CE) 3#if (_WINDOWS_CE)
4using System; 4using System;
5using System.Runtime.InteropServices; 5using System.Runtime.InteropServices;
6#endif 6#endif
7 7
8namespace Amib.Threading.Internal 8namespace Amib.Threading.Internal
9{ 9{
10 /// <summary> 10 /// <summary>
11 /// EventWaitHandleFactory class. 11 /// EventWaitHandleFactory class.
12 /// This is a static class that creates AutoResetEvent and ManualResetEvent objects. 12 /// This is a static class that creates AutoResetEvent and ManualResetEvent objects.
13 /// In WindowCE the WaitForMultipleObjects API fails to use the Handle property 13 /// In WindowCE the WaitForMultipleObjects API fails to use the Handle property
14 /// of XxxResetEvent. It can use only handles that were created by the CreateEvent API. 14 /// of XxxResetEvent. It can use only handles that were created by the CreateEvent API.
15 /// Consequently this class creates the needed XxxResetEvent and replaces the handle if 15 /// Consequently this class creates the needed XxxResetEvent and replaces the handle if
16 /// it's a WindowsCE OS. 16 /// it's a WindowsCE OS.
17 /// </summary> 17 /// </summary>
18 public static class EventWaitHandleFactory 18 public static class EventWaitHandleFactory
19 { 19 {
20 /// <summary> 20 /// <summary>
21 /// Create a new AutoResetEvent object 21 /// Create a new AutoResetEvent object
22 /// </summary> 22 /// </summary>
23 /// <returns>Return a new AutoResetEvent object</returns> 23 /// <returns>Return a new AutoResetEvent object</returns>
24 public static AutoResetEvent CreateAutoResetEvent() 24 public static AutoResetEvent CreateAutoResetEvent()
25 { 25 {
26 AutoResetEvent waitHandle = new AutoResetEvent(false); 26 AutoResetEvent waitHandle = new AutoResetEvent(false);
27 27
28#if (_WINDOWS_CE) 28#if (_WINDOWS_CE)
29 ReplaceEventHandle(waitHandle, false, false); 29 ReplaceEventHandle(waitHandle, false, false);
30#endif 30#endif
31 31
32 return waitHandle; 32 return waitHandle;
33 } 33 }
34 34
35 /// <summary> 35 /// <summary>
36 /// Create a new ManualResetEvent object 36 /// Create a new ManualResetEvent object
37 /// </summary> 37 /// </summary>
38 /// <returns>Return a new ManualResetEvent object</returns> 38 /// <returns>Return a new ManualResetEvent object</returns>
39 public static ManualResetEvent CreateManualResetEvent(bool initialState) 39 public static ManualResetEvent CreateManualResetEvent(bool initialState)
40 { 40 {
41 ManualResetEvent waitHandle = new ManualResetEvent(initialState); 41 ManualResetEvent waitHandle = new ManualResetEvent(initialState);
42 42
43#if (_WINDOWS_CE) 43#if (_WINDOWS_CE)
44 ReplaceEventHandle(waitHandle, true, initialState); 44 ReplaceEventHandle(waitHandle, true, initialState);
45#endif 45#endif
46 46
47 return waitHandle; 47 return waitHandle;
48 } 48 }
49 49
50#if (_WINDOWS_CE) 50#if (_WINDOWS_CE)
51 51
52 /// <summary> 52 /// <summary>
53 /// Replace the event handle 53 /// Replace the event handle
54 /// </summary> 54 /// </summary>
55 /// <param name="waitHandle">The WaitHandle object which its handle needs to be replaced.</param> 55 /// <param name="waitHandle">The WaitHandle object which its handle needs to be replaced.</param>
56 /// <param name="manualReset">Indicates if the event is a ManualResetEvent (true) or an AutoResetEvent (false)</param> 56 /// <param name="manualReset">Indicates if the event is a ManualResetEvent (true) or an AutoResetEvent (false)</param>
57 /// <param name="initialState">The initial state of the event</param> 57 /// <param name="initialState">The initial state of the event</param>
58 private static void ReplaceEventHandle(WaitHandle waitHandle, bool manualReset, bool initialState) 58 private static void ReplaceEventHandle(WaitHandle waitHandle, bool manualReset, bool initialState)
59 { 59 {
60 // Store the old handle 60 // Store the old handle
61 IntPtr oldHandle = waitHandle.Handle; 61 IntPtr oldHandle = waitHandle.Handle;
62 62
63 // Create a new event 63 // Create a new event
64 IntPtr newHandle = CreateEvent(IntPtr.Zero, manualReset, initialState, null); 64 IntPtr newHandle = CreateEvent(IntPtr.Zero, manualReset, initialState, null);
65 65
66 // Replace the old event with the new event 66 // Replace the old event with the new event
67 waitHandle.Handle = newHandle; 67 waitHandle.Handle = newHandle;
68 68
69 // Close the old event 69 // Close the old event
70 CloseHandle (oldHandle); 70 CloseHandle (oldHandle);
71 } 71 }
72 72
73 [DllImport("coredll.dll", SetLastError = true)] 73 [DllImport("coredll.dll", SetLastError = true)]
74 public static extern IntPtr CreateEvent(IntPtr lpEventAttributes, bool bManualReset, bool bInitialState, string lpName); 74 public static extern IntPtr CreateEvent(IntPtr lpEventAttributes, bool bManualReset, bool bInitialState, string lpName);
75 75
76 //Handle 76 //Handle
77 [DllImport("coredll.dll", SetLastError = true)] 77 [DllImport("coredll.dll", SetLastError = true)]
78 public static extern bool CloseHandle(IntPtr hObject); 78 public static extern bool CloseHandle(IntPtr hObject);
79#endif 79#endif
80 80
81 } 81 }
82} 82}
diff --git a/ThirdParty/SmartThreadPool/Exceptions.cs b/ThirdParty/SmartThreadPool/Exceptions.cs
index 8e66ce9..6c6a88b 100644
--- a/ThirdParty/SmartThreadPool/Exceptions.cs
+++ b/ThirdParty/SmartThreadPool/Exceptions.cs
@@ -1,111 +1,111 @@
1using System; 1using System;
2#if !(_WINDOWS_CE) 2#if !(_WINDOWS_CE)
3using System.Runtime.Serialization; 3using System.Runtime.Serialization;
4#endif 4#endif
5 5
6namespace Amib.Threading 6namespace Amib.Threading
7{ 7{
8 #region Exceptions 8 #region Exceptions
9 9
10 /// <summary> 10 /// <summary>
11 /// Represents an exception in case IWorkItemResult.GetResult has been canceled 11 /// Represents an exception in case IWorkItemResult.GetResult has been canceled
12 /// </summary> 12 /// </summary>
13 public sealed partial class WorkItemCancelException : Exception 13 public sealed partial class WorkItemCancelException : Exception
14 { 14 {
15 public WorkItemCancelException() 15 public WorkItemCancelException()
16 { 16 {
17 } 17 }
18 18
19 public WorkItemCancelException(string message) 19 public WorkItemCancelException(string message)
20 : base(message) 20 : base(message)
21 { 21 {
22 } 22 }
23 23
24 public WorkItemCancelException(string message, Exception e) 24 public WorkItemCancelException(string message, Exception e)
25 : base(message, e) 25 : base(message, e)
26 { 26 {
27 } 27 }
28 } 28 }
29 29
30 /// <summary> 30 /// <summary>
31 /// Represents an exception in case IWorkItemResult.GetResult has been timed out 31 /// Represents an exception in case IWorkItemResult.GetResult has been timed out
32 /// </summary> 32 /// </summary>
33 public sealed partial class WorkItemTimeoutException : Exception 33 public sealed partial class WorkItemTimeoutException : Exception
34 { 34 {
35 public WorkItemTimeoutException() 35 public WorkItemTimeoutException()
36 { 36 {
37 } 37 }
38 38
39 public WorkItemTimeoutException(string message) 39 public WorkItemTimeoutException(string message)
40 : base(message) 40 : base(message)
41 { 41 {
42 } 42 }
43 43
44 public WorkItemTimeoutException(string message, Exception e) 44 public WorkItemTimeoutException(string message, Exception e)
45 : base(message, e) 45 : base(message, e)
46 { 46 {
47 } 47 }
48 } 48 }
49 49
50 /// <summary> 50 /// <summary>
51 /// Represents an exception in case IWorkItemResult.GetResult has been timed out 51 /// Represents an exception in case IWorkItemResult.GetResult has been timed out
52 /// </summary> 52 /// </summary>
53 public sealed partial class WorkItemResultException : Exception 53 public sealed partial class WorkItemResultException : Exception
54 { 54 {
55 public WorkItemResultException() 55 public WorkItemResultException()
56 { 56 {
57 } 57 }
58 58
59 public WorkItemResultException(string message) 59 public WorkItemResultException(string message)
60 : base(message) 60 : base(message)
61 { 61 {
62 } 62 }
63 63
64 public WorkItemResultException(string message, Exception e) 64 public WorkItemResultException(string message, Exception e)
65 : base(message, e) 65 : base(message, e)
66 { 66 {
67 } 67 }
68 } 68 }
69 69
70 70
71#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE) 71#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
72 /// <summary> 72 /// <summary>
73 /// Represents an exception in case IWorkItemResult.GetResult has been canceled 73 /// Represents an exception in case IWorkItemResult.GetResult has been canceled
74 /// </summary> 74 /// </summary>
75 [Serializable] 75 [Serializable]
76 public sealed partial class WorkItemCancelException 76 public sealed partial class WorkItemCancelException
77 { 77 {
78 public WorkItemCancelException(SerializationInfo si, StreamingContext sc) 78 public WorkItemCancelException(SerializationInfo si, StreamingContext sc)
79 : base(si, sc) 79 : base(si, sc)
80 { 80 {
81 } 81 }
82 } 82 }
83 83
84 /// <summary> 84 /// <summary>
85 /// Represents an exception in case IWorkItemResult.GetResult has been timed out 85 /// Represents an exception in case IWorkItemResult.GetResult has been timed out
86 /// </summary> 86 /// </summary>
87 [Serializable] 87 [Serializable]
88 public sealed partial class WorkItemTimeoutException 88 public sealed partial class WorkItemTimeoutException
89 { 89 {
90 public WorkItemTimeoutException(SerializationInfo si, StreamingContext sc) 90 public WorkItemTimeoutException(SerializationInfo si, StreamingContext sc)
91 : base(si, sc) 91 : base(si, sc)
92 { 92 {
93 } 93 }
94 } 94 }
95 95
96 /// <summary> 96 /// <summary>
97 /// Represents an exception in case IWorkItemResult.GetResult has been timed out 97 /// Represents an exception in case IWorkItemResult.GetResult has been timed out
98 /// </summary> 98 /// </summary>
99 [Serializable] 99 [Serializable]
100 public sealed partial class WorkItemResultException 100 public sealed partial class WorkItemResultException
101 { 101 {
102 public WorkItemResultException(SerializationInfo si, StreamingContext sc) 102 public WorkItemResultException(SerializationInfo si, StreamingContext sc)
103 : base(si, sc) 103 : base(si, sc)
104 { 104 {
105 } 105 }
106 } 106 }
107 107
108#endif 108#endif
109 109
110 #endregion 110 #endregion
111} 111}
diff --git a/ThirdParty/SmartThreadPool/Interfaces.cs b/ThirdParty/SmartThreadPool/Interfaces.cs
index 29c8a3e..513422f 100644
--- a/ThirdParty/SmartThreadPool/Interfaces.cs
+++ b/ThirdParty/SmartThreadPool/Interfaces.cs
@@ -1,628 +1,628 @@
1using System; 1using System;
2using System.Threading; 2using System.Threading;
3 3
4namespace Amib.Threading 4namespace Amib.Threading
5{ 5{
6 #region Delegates 6 #region Delegates
7 7
8 /// <summary> 8 /// <summary>
9 /// A delegate that represents the method to run as the work item 9 /// A delegate that represents the method to run as the work item
10 /// </summary> 10 /// </summary>
11 /// <param name="state">A state object for the method to run</param> 11 /// <param name="state">A state object for the method to run</param>
12 public delegate object WorkItemCallback(object state); 12 public delegate object WorkItemCallback(object state);
13 13
14 /// <summary> 14 /// <summary>
15 /// A delegate to call after the WorkItemCallback completed 15 /// A delegate to call after the WorkItemCallback completed
16 /// </summary> 16 /// </summary>
17 /// <param name="wir">The work item result object</param> 17 /// <param name="wir">The work item result object</param>
18 public delegate void PostExecuteWorkItemCallback(IWorkItemResult wir); 18 public delegate void PostExecuteWorkItemCallback(IWorkItemResult wir);
19 19
20 /// <summary> 20 /// <summary>
21 /// A delegate to call after the WorkItemCallback completed 21 /// A delegate to call after the WorkItemCallback completed
22 /// </summary> 22 /// </summary>
23 /// <param name="wir">The work item result object</param> 23 /// <param name="wir">The work item result object</param>
24 public delegate void PostExecuteWorkItemCallback<TResult>(IWorkItemResult<TResult> wir); 24 public delegate void PostExecuteWorkItemCallback<TResult>(IWorkItemResult<TResult> wir);
25 25
26 /// <summary> 26 /// <summary>
27 /// A delegate to call when a WorkItemsGroup becomes idle 27 /// A delegate to call when a WorkItemsGroup becomes idle
28 /// </summary> 28 /// </summary>
29 /// <param name="workItemsGroup">A reference to the WorkItemsGroup that became idle</param> 29 /// <param name="workItemsGroup">A reference to the WorkItemsGroup that became idle</param>
30 public delegate void WorkItemsGroupIdleHandler(IWorkItemsGroup workItemsGroup); 30 public delegate void WorkItemsGroupIdleHandler(IWorkItemsGroup workItemsGroup);
31 31
32 /// <summary> 32 /// <summary>
33 /// A delegate to call after a thread is created, but before 33 /// A delegate to call after a thread is created, but before
34 /// it's first use. 34 /// it's first use.
35 /// </summary> 35 /// </summary>
36 public delegate void ThreadInitializationHandler(); 36 public delegate void ThreadInitializationHandler();
37 37
38 /// <summary> 38 /// <summary>
39 /// A delegate to call when a thread is about to exit, after 39 /// A delegate to call when a thread is about to exit, after
40 /// it is no longer belong to the pool. 40 /// it is no longer belong to the pool.
41 /// </summary> 41 /// </summary>
42 public delegate void ThreadTerminationHandler(); 42 public delegate void ThreadTerminationHandler();
43 43
44 #endregion 44 #endregion
45 45
46 #region WorkItem Priority 46 #region WorkItem Priority
47 47
48 /// <summary> 48 /// <summary>
49 /// Defines the availeable priorities of a work item. 49 /// Defines the availeable priorities of a work item.
50 /// The higher the priority a work item has, the sooner 50 /// The higher the priority a work item has, the sooner
51 /// it will be executed. 51 /// it will be executed.
52 /// </summary> 52 /// </summary>
53 public enum WorkItemPriority 53 public enum WorkItemPriority
54 { 54 {
55 Lowest, 55 Lowest,
56 BelowNormal, 56 BelowNormal,
57 Normal, 57 Normal,
58 AboveNormal, 58 AboveNormal,
59 Highest, 59 Highest,
60 } 60 }
61 61
62 #endregion 62 #endregion
63 63
64 #region IWorkItemsGroup interface 64 #region IWorkItemsGroup interface
65 65
66 /// <summary> 66 /// <summary>
67 /// IWorkItemsGroup interface 67 /// IWorkItemsGroup interface
68 /// Created by SmartThreadPool.CreateWorkItemsGroup() 68 /// Created by SmartThreadPool.CreateWorkItemsGroup()
69 /// </summary> 69 /// </summary>
70 public interface IWorkItemsGroup 70 public interface IWorkItemsGroup
71 { 71 {
72 /// <summary> 72 /// <summary>
73 /// Get/Set the name of the WorkItemsGroup 73 /// Get/Set the name of the WorkItemsGroup
74 /// </summary> 74 /// </summary>
75 string Name { get; set; } 75 string Name { get; set; }
76 76
77 /// <summary> 77 /// <summary>
78 /// Get/Set the maximum number of workitem that execute cocurrency on the thread pool 78 /// Get/Set the maximum number of workitem that execute cocurrency on the thread pool
79 /// </summary> 79 /// </summary>
80 int Concurrency { get; set; } 80 int Concurrency { get; set; }
81 81
82 /// <summary> 82 /// <summary>
83 /// Get the number of work items waiting in the queue. 83 /// Get the number of work items waiting in the queue.
84 /// </summary> 84 /// </summary>
85 int WaitingCallbacks { get; } 85 int WaitingCallbacks { get; }
86 86
87 /// <summary> 87 /// <summary>
88 /// Get an array with all the state objects of the currently running items. 88 /// Get an array with all the state objects of the currently running items.
89 /// The array represents a snap shot and impact performance. 89 /// The array represents a snap shot and impact performance.
90 /// </summary> 90 /// </summary>
91 object[] GetStates(); 91 object[] GetStates();
92 92
93 /// <summary> 93 /// <summary>
94 /// Get the WorkItemsGroup start information 94 /// Get the WorkItemsGroup start information
95 /// </summary> 95 /// </summary>
96 WIGStartInfo WIGStartInfo { get; } 96 WIGStartInfo WIGStartInfo { get; }
97 97
98 /// <summary> 98 /// <summary>
99 /// Starts to execute work items 99 /// Starts to execute work items
100 /// </summary> 100 /// </summary>
101 void Start(); 101 void Start();
102 102
103 /// <summary> 103 /// <summary>
104 /// Cancel all the work items. 104 /// Cancel all the work items.
105 /// Same as Cancel(false) 105 /// Same as Cancel(false)
106 /// </summary> 106 /// </summary>
107 void Cancel(); 107 void Cancel();
108 108
109 /// <summary> 109 /// <summary>
110 /// Cancel all work items using thread abortion 110 /// Cancel all work items using thread abortion
111 /// </summary> 111 /// </summary>
112 /// <param name="abortExecution">True to stop work items by raising ThreadAbortException</param> 112 /// <param name="abortExecution">True to stop work items by raising ThreadAbortException</param>
113 void Cancel(bool abortExecution); 113 void Cancel(bool abortExecution);
114 114
115 /// <summary> 115 /// <summary>
116 /// Wait for all work item to complete. 116 /// Wait for all work item to complete.
117 /// </summary> 117 /// </summary>
118 void WaitForIdle(); 118 void WaitForIdle();
119 119
120 /// <summary> 120 /// <summary>
121 /// Wait for all work item to complete, until timeout expired 121 /// Wait for all work item to complete, until timeout expired
122 /// </summary> 122 /// </summary>
123 /// <param name="timeout">How long to wait for the work items to complete</param> 123 /// <param name="timeout">How long to wait for the work items to complete</param>
124 /// <returns>Returns true if work items completed within the timeout, otherwise false.</returns> 124 /// <returns>Returns true if work items completed within the timeout, otherwise false.</returns>
125 bool WaitForIdle(TimeSpan timeout); 125 bool WaitForIdle(TimeSpan timeout);
126 126
127 /// <summary> 127 /// <summary>
128 /// Wait for all work item to complete, until timeout expired 128 /// Wait for all work item to complete, until timeout expired
129 /// </summary> 129 /// </summary>
130 /// <param name="millisecondsTimeout">How long to wait for the work items to complete in milliseconds</param> 130 /// <param name="millisecondsTimeout">How long to wait for the work items to complete in milliseconds</param>
131 /// <returns>Returns true if work items completed within the timeout, otherwise false.</returns> 131 /// <returns>Returns true if work items completed within the timeout, otherwise false.</returns>
132 bool WaitForIdle(int millisecondsTimeout); 132 bool WaitForIdle(int millisecondsTimeout);
133 133
134 /// <summary> 134 /// <summary>
135 /// IsIdle is true when there are no work items running or queued. 135 /// IsIdle is true when there are no work items running or queued.
136 /// </summary> 136 /// </summary>
137 bool IsIdle { get; } 137 bool IsIdle { get; }
138 138
139 /// <summary> 139 /// <summary>
140 /// This event is fired when all work items are completed. 140 /// This event is fired when all work items are completed.
141 /// (When IsIdle changes to true) 141 /// (When IsIdle changes to true)
142 /// This event only work on WorkItemsGroup. On SmartThreadPool 142 /// This event only work on WorkItemsGroup. On SmartThreadPool
143 /// it throws the NotImplementedException. 143 /// it throws the NotImplementedException.
144 /// </summary> 144 /// </summary>
145 event WorkItemsGroupIdleHandler OnIdle; 145 event WorkItemsGroupIdleHandler OnIdle;
146 146
147 #region QueueWorkItem 147 #region QueueWorkItem
148 148
149 /// <summary> 149 /// <summary>
150 /// Queue a work item 150 /// Queue a work item
151 /// </summary> 151 /// </summary>
152 /// <param name="callback">A callback to execute</param> 152 /// <param name="callback">A callback to execute</param>
153 /// <returns>Returns a work item result</returns> 153 /// <returns>Returns a work item result</returns>
154 IWorkItemResult QueueWorkItem(WorkItemCallback callback); 154 IWorkItemResult QueueWorkItem(WorkItemCallback callback);
155 155
156 /// <summary> 156 /// <summary>
157 /// Queue a work item 157 /// Queue a work item
158 /// </summary> 158 /// </summary>
159 /// <param name="callback">A callback to execute</param> 159 /// <param name="callback">A callback to execute</param>
160 /// <param name="workItemPriority">The priority of the work item</param> 160 /// <param name="workItemPriority">The priority of the work item</param>
161 /// <returns>Returns a work item result</returns> 161 /// <returns>Returns a work item result</returns>
162 IWorkItemResult QueueWorkItem(WorkItemCallback callback, WorkItemPriority workItemPriority); 162 IWorkItemResult QueueWorkItem(WorkItemCallback callback, WorkItemPriority workItemPriority);
163 163
164 /// <summary> 164 /// <summary>
165 /// Queue a work item 165 /// Queue a work item
166 /// </summary> 166 /// </summary>
167 /// <param name="callback">A callback to execute</param> 167 /// <param name="callback">A callback to execute</param>
168 /// <param name="state"> 168 /// <param name="state">
169 /// The context object of the work item. Used for passing arguments to the work item. 169 /// The context object of the work item. Used for passing arguments to the work item.
170 /// </param> 170 /// </param>
171 /// <returns>Returns a work item result</returns> 171 /// <returns>Returns a work item result</returns>
172 IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state); 172 IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state);
173 173
174 /// <summary> 174 /// <summary>
175 /// Queue a work item 175 /// Queue a work item
176 /// </summary> 176 /// </summary>
177 /// <param name="callback">A callback to execute</param> 177 /// <param name="callback">A callback to execute</param>
178 /// <param name="state"> 178 /// <param name="state">
179 /// The context object of the work item. Used for passing arguments to the work item. 179 /// The context object of the work item. Used for passing arguments to the work item.
180 /// </param> 180 /// </param>
181 /// <param name="workItemPriority">The work item priority</param> 181 /// <param name="workItemPriority">The work item priority</param>
182 /// <returns>Returns a work item result</returns> 182 /// <returns>Returns a work item result</returns>
183 IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, WorkItemPriority workItemPriority); 183 IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, WorkItemPriority workItemPriority);
184 184
185 /// <summary> 185 /// <summary>
186 /// Queue a work item 186 /// Queue a work item
187 /// </summary> 187 /// </summary>
188 /// <param name="callback">A callback to execute</param> 188 /// <param name="callback">A callback to execute</param>
189 /// <param name="state"> 189 /// <param name="state">
190 /// The context object of the work item. Used for passing arguments to the work item. 190 /// The context object of the work item. Used for passing arguments to the work item.
191 /// </param> 191 /// </param>
192 /// <param name="postExecuteWorkItemCallback"> 192 /// <param name="postExecuteWorkItemCallback">
193 /// A delegate to call after the callback completion 193 /// A delegate to call after the callback completion
194 /// </param> 194 /// </param>
195 /// <returns>Returns a work item result</returns> 195 /// <returns>Returns a work item result</returns>
196 IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback); 196 IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback);
197 197
198 /// <summary> 198 /// <summary>
199 /// Queue a work item 199 /// Queue a work item
200 /// </summary> 200 /// </summary>
201 /// <param name="callback">A callback to execute</param> 201 /// <param name="callback">A callback to execute</param>
202 /// <param name="state"> 202 /// <param name="state">
203 /// The context object of the work item. Used for passing arguments to the work item. 203 /// The context object of the work item. Used for passing arguments to the work item.
204 /// </param> 204 /// </param>
205 /// <param name="postExecuteWorkItemCallback"> 205 /// <param name="postExecuteWorkItemCallback">
206 /// A delegate to call after the callback completion 206 /// A delegate to call after the callback completion
207 /// </param> 207 /// </param>
208 /// <param name="workItemPriority">The work item priority</param> 208 /// <param name="workItemPriority">The work item priority</param>
209 /// <returns>Returns a work item result</returns> 209 /// <returns>Returns a work item result</returns>
210 IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, WorkItemPriority workItemPriority); 210 IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, WorkItemPriority workItemPriority);
211 211
212 /// <summary> 212 /// <summary>
213 /// Queue a work item 213 /// Queue a work item
214 /// </summary> 214 /// </summary>
215 /// <param name="callback">A callback to execute</param> 215 /// <param name="callback">A callback to execute</param>
216 /// <param name="state"> 216 /// <param name="state">
217 /// The context object of the work item. Used for passing arguments to the work item. 217 /// The context object of the work item. Used for passing arguments to the work item.
218 /// </param> 218 /// </param>
219 /// <param name="postExecuteWorkItemCallback"> 219 /// <param name="postExecuteWorkItemCallback">
220 /// A delegate to call after the callback completion 220 /// A delegate to call after the callback completion
221 /// </param> 221 /// </param>
222 /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param> 222 /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
223 /// <returns>Returns a work item result</returns> 223 /// <returns>Returns a work item result</returns>
224 IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute); 224 IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute);
225 225
226 /// <summary> 226 /// <summary>
227 /// Queue a work item 227 /// Queue a work item
228 /// </summary> 228 /// </summary>
229 /// <param name="callback">A callback to execute</param> 229 /// <param name="callback">A callback to execute</param>
230 /// <param name="state"> 230 /// <param name="state">
231 /// The context object of the work item. Used for passing arguments to the work item. 231 /// The context object of the work item. Used for passing arguments to the work item.
232 /// </param> 232 /// </param>
233 /// <param name="postExecuteWorkItemCallback"> 233 /// <param name="postExecuteWorkItemCallback">
234 /// A delegate to call after the callback completion 234 /// A delegate to call after the callback completion
235 /// </param> 235 /// </param>
236 /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param> 236 /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
237 /// <param name="workItemPriority">The work item priority</param> 237 /// <param name="workItemPriority">The work item priority</param>
238 /// <returns>Returns a work item result</returns> 238 /// <returns>Returns a work item result</returns>
239 IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute, WorkItemPriority workItemPriority); 239 IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute, WorkItemPriority workItemPriority);
240 240
241 /// <summary> 241 /// <summary>
242 /// Queue a work item 242 /// Queue a work item
243 /// </summary> 243 /// </summary>
244 /// <param name="workItemInfo">Work item info</param> 244 /// <param name="workItemInfo">Work item info</param>
245 /// <param name="callback">A callback to execute</param> 245 /// <param name="callback">A callback to execute</param>
246 /// <returns>Returns a work item result</returns> 246 /// <returns>Returns a work item result</returns>
247 IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback); 247 IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback);
248 248
249 /// <summary> 249 /// <summary>
250 /// Queue a work item 250 /// Queue a work item
251 /// </summary> 251 /// </summary>
252 /// <param name="workItemInfo">Work item information</param> 252 /// <param name="workItemInfo">Work item information</param>
253 /// <param name="callback">A callback to execute</param> 253 /// <param name="callback">A callback to execute</param>
254 /// <param name="state"> 254 /// <param name="state">
255 /// The context object of the work item. Used for passing arguments to the work item. 255 /// The context object of the work item. Used for passing arguments to the work item.
256 /// </param> 256 /// </param>
257 /// <returns>Returns a work item result</returns> 257 /// <returns>Returns a work item result</returns>
258 IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state); 258 IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state);
259 259
260 #endregion 260 #endregion
261 261
262 #region QueueWorkItem(Action<...>) 262 #region QueueWorkItem(Action<...>)
263 263
264 /// <summary> 264 /// <summary>
265 /// Queue a work item. 265 /// Queue a work item.
266 /// </summary> 266 /// </summary>
267 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns> 267 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
268 IWorkItemResult QueueWorkItem(Action action); 268 IWorkItemResult QueueWorkItem(Action action);
269 269
270 /// <summary> 270 /// <summary>
271 /// Queue a work item. 271 /// Queue a work item.
272 /// </summary> 272 /// </summary>
273 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns> 273 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
274 IWorkItemResult QueueWorkItem (Action action, WorkItemPriority priority); 274 IWorkItemResult QueueWorkItem (Action action, WorkItemPriority priority);
275 275
276 /// <summary> 276 /// <summary>
277 /// Queue a work item. 277 /// Queue a work item.
278 /// </summary> 278 /// </summary>
279 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns> 279 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
280 IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg, WorkItemPriority priority); 280 IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg, WorkItemPriority priority);
281 281
282 /// <summary> 282 /// <summary>
283 /// Queue a work item. 283 /// Queue a work item.
284 /// </summary> 284 /// </summary>
285 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns> 285 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
286 IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg); 286 IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg);
287 287
288 /// <summary> 288 /// <summary>
289 /// Queue a work item. 289 /// Queue a work item.
290 /// </summary> 290 /// </summary>
291 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns> 291 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
292 IWorkItemResult QueueWorkItem<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2); 292 IWorkItemResult QueueWorkItem<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2);
293 293
294 /// <summary> 294 /// <summary>
295 /// Queue a work item. 295 /// Queue a work item.
296 /// </summary> 296 /// </summary>
297 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns> 297 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
298 IWorkItemResult QueueWorkItem<T1, T2> (Action<T1, T2> action, T1 arg1, T2 arg2, WorkItemPriority priority); 298 IWorkItemResult QueueWorkItem<T1, T2> (Action<T1, T2> action, T1 arg1, T2 arg2, WorkItemPriority priority);
299 299
300 /// <summary> 300 /// <summary>
301 /// Queue a work item. 301 /// Queue a work item.
302 /// </summary> 302 /// </summary>
303 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns> 303 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
304 IWorkItemResult QueueWorkItem<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3); 304 IWorkItemResult QueueWorkItem<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3);
305 305
306 /// <summary> 306 /// <summary>
307 /// Queue a work item. 307 /// Queue a work item.
308 /// </summary> 308 /// </summary>
309 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns> 309 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
310 IWorkItemResult QueueWorkItem<T1, T2, T3> (Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3, WorkItemPriority priority); 310 IWorkItemResult QueueWorkItem<T1, T2, T3> (Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3, WorkItemPriority priority);
311 311
312 /// <summary> 312 /// <summary>
313 /// Queue a work item. 313 /// Queue a work item.
314 /// </summary> 314 /// </summary>
315 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns> 315 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
316 IWorkItemResult QueueWorkItem<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4); 316 IWorkItemResult QueueWorkItem<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4);
317 317
318 /// <summary> 318 /// <summary>
319 /// Queue a work item. 319 /// Queue a work item.
320 /// </summary> 320 /// </summary>
321 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns> 321 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
322 IWorkItemResult QueueWorkItem<T1, T2, T3, T4> (Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, WorkItemPriority priority); 322 IWorkItemResult QueueWorkItem<T1, T2, T3, T4> (Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, WorkItemPriority priority);
323 323
324 #endregion 324 #endregion
325 325
326 #region QueueWorkItem(Func<...>) 326 #region QueueWorkItem(Func<...>)
327 327
328 /// <summary> 328 /// <summary>
329 /// Queue a work item. 329 /// Queue a work item.
330 /// </summary> 330 /// </summary>
331 /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object. 331 /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object.
332 /// its GetResult() returns a TResult object</returns> 332 /// its GetResult() returns a TResult object</returns>
333 IWorkItemResult<TResult> QueueWorkItem<TResult>(Func<TResult> func); 333 IWorkItemResult<TResult> QueueWorkItem<TResult>(Func<TResult> func);
334 334
335 /// <summary> 335 /// <summary>
336 /// Queue a work item. 336 /// Queue a work item.
337 /// </summary> 337 /// </summary>
338 /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object. 338 /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object.
339 /// its GetResult() returns a TResult object</returns> 339 /// its GetResult() returns a TResult object</returns>
340 IWorkItemResult<TResult> QueueWorkItem<T, TResult>(Func<T, TResult> func, T arg); 340 IWorkItemResult<TResult> QueueWorkItem<T, TResult>(Func<T, TResult> func, T arg);
341 341
342 /// <summary> 342 /// <summary>
343 /// Queue a work item. 343 /// Queue a work item.
344 /// </summary> 344 /// </summary>
345 /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object. 345 /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object.
346 /// its GetResult() returns a TResult object</returns> 346 /// its GetResult() returns a TResult object</returns>
347 IWorkItemResult<TResult> QueueWorkItem<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 arg1, T2 arg2); 347 IWorkItemResult<TResult> QueueWorkItem<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 arg1, T2 arg2);
348 348
349 /// <summary> 349 /// <summary>
350 /// Queue a work item. 350 /// Queue a work item.
351 /// </summary> 351 /// </summary>
352 /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object. 352 /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object.
353 /// its GetResult() returns a TResult object</returns> 353 /// its GetResult() returns a TResult object</returns>
354 IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> func, T1 arg1, T2 arg2, T3 arg3); 354 IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> func, T1 arg1, T2 arg2, T3 arg3);
355 355
356 /// <summary> 356 /// <summary>
357 /// Queue a work item. 357 /// Queue a work item.
358 /// </summary> 358 /// </summary>
359 /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object. 359 /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object.
360 /// its GetResult() returns a TResult object</returns> 360 /// its GetResult() returns a TResult object</returns>
361 IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, T4, TResult>(Func<T1, T2, T3, T4, TResult> func, T1 arg1, T2 arg2, T3 arg3, T4 arg4); 361 IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, T4, TResult>(Func<T1, T2, T3, T4, TResult> func, T1 arg1, T2 arg2, T3 arg3, T4 arg4);
362 362
363 #endregion 363 #endregion
364 } 364 }
365 365
366 #endregion 366 #endregion
367 367
368 #region CallToPostExecute enumerator 368 #region CallToPostExecute enumerator
369 369
370 [Flags] 370 [Flags]
371 public enum CallToPostExecute 371 public enum CallToPostExecute
372 { 372 {
373 /// <summary> 373 /// <summary>
374 /// Never call to the PostExecute call back 374 /// Never call to the PostExecute call back
375 /// </summary> 375 /// </summary>
376 Never = 0x00, 376 Never = 0x00,
377 377
378 /// <summary> 378 /// <summary>
379 /// Call to the PostExecute only when the work item is cancelled 379 /// Call to the PostExecute only when the work item is cancelled
380 /// </summary> 380 /// </summary>
381 WhenWorkItemCanceled = 0x01, 381 WhenWorkItemCanceled = 0x01,
382 382
383 /// <summary> 383 /// <summary>
384 /// Call to the PostExecute only when the work item is not cancelled 384 /// Call to the PostExecute only when the work item is not cancelled
385 /// </summary> 385 /// </summary>
386 WhenWorkItemNotCanceled = 0x02, 386 WhenWorkItemNotCanceled = 0x02,
387 387
388 /// <summary> 388 /// <summary>
389 /// Always call to the PostExecute 389 /// Always call to the PostExecute
390 /// </summary> 390 /// </summary>
391 Always = WhenWorkItemCanceled | WhenWorkItemNotCanceled, 391 Always = WhenWorkItemCanceled | WhenWorkItemNotCanceled,
392 } 392 }
393 393
394 #endregion 394 #endregion
395 395
396 #region IWorkItemResult interface 396 #region IWorkItemResult interface
397 397
398 /// <summary> 398 /// <summary>
399 /// The common interface of IWorkItemResult and IWorkItemResult&lt;T&gt; 399 /// The common interface of IWorkItemResult and IWorkItemResult&lt;T&gt;
400 /// </summary> 400 /// </summary>
401 public interface IWaitableResult 401 public interface IWaitableResult
402 { 402 {
403 /// <summary> 403 /// <summary>
404 /// This method intent is for internal use. 404 /// This method intent is for internal use.
405 /// </summary> 405 /// </summary>
406 /// <returns></returns> 406 /// <returns></returns>
407 IWorkItemResult GetWorkItemResult(); 407 IWorkItemResult GetWorkItemResult();
408 408
409 /// <summary> 409 /// <summary>
410 /// This method intent is for internal use. 410 /// This method intent is for internal use.
411 /// </summary> 411 /// </summary>
412 /// <returns></returns> 412 /// <returns></returns>
413 IWorkItemResult<TResult> GetWorkItemResultT<TResult>(); 413 IWorkItemResult<TResult> GetWorkItemResultT<TResult>();
414 } 414 }
415 415
416 /// <summary> 416 /// <summary>
417 /// IWorkItemResult interface. 417 /// IWorkItemResult interface.
418 /// Created when a WorkItemCallback work item is queued. 418 /// Created when a WorkItemCallback work item is queued.
419 /// </summary> 419 /// </summary>
420 public interface IWorkItemResult : IWorkItemResult<object> 420 public interface IWorkItemResult : IWorkItemResult<object>
421 { 421 {
422 } 422 }
423 423
424 /// <summary> 424 /// <summary>
425 /// IWorkItemResult&lt;TResult&gt; interface. 425 /// IWorkItemResult&lt;TResult&gt; interface.
426 /// Created when a Func&lt;TResult&gt; work item is queued. 426 /// Created when a Func&lt;TResult&gt; work item is queued.
427 /// </summary> 427 /// </summary>
428 public interface IWorkItemResult<TResult> : IWaitableResult 428 public interface IWorkItemResult<TResult> : IWaitableResult
429 { 429 {
430 /// <summary> 430 /// <summary>
431 /// Get the result of the work item. 431 /// Get the result of the work item.
432 /// If the work item didn't run yet then the caller waits. 432 /// If the work item didn't run yet then the caller waits.
433 /// </summary> 433 /// </summary>
434 /// <returns>The result of the work item</returns> 434 /// <returns>The result of the work item</returns>
435 TResult GetResult(); 435 TResult GetResult();
436 436
437 /// <summary> 437 /// <summary>
438 /// Get the result of the work item. 438 /// Get the result of the work item.
439 /// If the work item didn't run yet then the caller waits until timeout. 439 /// If the work item didn't run yet then the caller waits until timeout.
440 /// </summary> 440 /// </summary>
441 /// <returns>The result of the work item</returns> 441 /// <returns>The result of the work item</returns>
442 /// On timeout throws WorkItemTimeoutException 442 /// On timeout throws WorkItemTimeoutException
443 TResult GetResult( 443 TResult GetResult(
444 int millisecondsTimeout, 444 int millisecondsTimeout,
445 bool exitContext); 445 bool exitContext);
446 446
447 /// <summary> 447 /// <summary>
448 /// Get the result of the work item. 448 /// Get the result of the work item.
449 /// If the work item didn't run yet then the caller waits until timeout. 449 /// If the work item didn't run yet then the caller waits until timeout.
450 /// </summary> 450 /// </summary>
451 /// <returns>The result of the work item</returns> 451 /// <returns>The result of the work item</returns>
452 /// On timeout throws WorkItemTimeoutException 452 /// On timeout throws WorkItemTimeoutException
453 TResult GetResult( 453 TResult GetResult(
454 TimeSpan timeout, 454 TimeSpan timeout,
455 bool exitContext); 455 bool exitContext);
456 456
457 /// <summary> 457 /// <summary>
458 /// Get the result of the work item. 458 /// Get the result of the work item.
459 /// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled. 459 /// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
460 /// </summary> 460 /// </summary>
461 /// <param name="millisecondsTimeout">Timeout in milliseconds, or -1 for infinite</param> 461 /// <param name="millisecondsTimeout">Timeout in milliseconds, or -1 for infinite</param>
462 /// <param name="exitContext"> 462 /// <param name="exitContext">
463 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 463 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
464 /// </param> 464 /// </param>
465 /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the blocking if needed</param> 465 /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the blocking if needed</param>
466 /// <returns>The result of the work item</returns> 466 /// <returns>The result of the work item</returns>
467 /// On timeout throws WorkItemTimeoutException 467 /// On timeout throws WorkItemTimeoutException
468 /// On cancel throws WorkItemCancelException 468 /// On cancel throws WorkItemCancelException
469 TResult GetResult( 469 TResult GetResult(
470 int millisecondsTimeout, 470 int millisecondsTimeout,
471 bool exitContext, 471 bool exitContext,
472 WaitHandle cancelWaitHandle); 472 WaitHandle cancelWaitHandle);
473 473
474 /// <summary> 474 /// <summary>
475 /// Get the result of the work item. 475 /// Get the result of the work item.
476 /// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled. 476 /// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
477 /// </summary> 477 /// </summary>
478 /// <returns>The result of the work item</returns> 478 /// <returns>The result of the work item</returns>
479 /// On timeout throws WorkItemTimeoutException 479 /// On timeout throws WorkItemTimeoutException
480 /// On cancel throws WorkItemCancelException 480 /// On cancel throws WorkItemCancelException
481 TResult GetResult( 481 TResult GetResult(
482 TimeSpan timeout, 482 TimeSpan timeout,
483 bool exitContext, 483 bool exitContext,
484 WaitHandle cancelWaitHandle); 484 WaitHandle cancelWaitHandle);
485 485
486 /// <summary> 486 /// <summary>
487 /// Get the result of the work item. 487 /// Get the result of the work item.
488 /// If the work item didn't run yet then the caller waits. 488 /// If the work item didn't run yet then the caller waits.
489 /// </summary> 489 /// </summary>
490 /// <param name="e">Filled with the exception if one was thrown</param> 490 /// <param name="e">Filled with the exception if one was thrown</param>
491 /// <returns>The result of the work item</returns> 491 /// <returns>The result of the work item</returns>
492 TResult GetResult(out Exception e); 492 TResult GetResult(out Exception e);
493 493
494 /// <summary> 494 /// <summary>
495 /// Get the result of the work item. 495 /// Get the result of the work item.
496 /// If the work item didn't run yet then the caller waits until timeout. 496 /// If the work item didn't run yet then the caller waits until timeout.
497 /// </summary> 497 /// </summary>
498 /// <param name="millisecondsTimeout"></param> 498 /// <param name="millisecondsTimeout"></param>
499 /// <param name="exitContext"></param> 499 /// <param name="exitContext"></param>
500 /// <param name="e">Filled with the exception if one was thrown</param> 500 /// <param name="e">Filled with the exception if one was thrown</param>
501 /// <returns>The result of the work item</returns> 501 /// <returns>The result of the work item</returns>
502 /// On timeout throws WorkItemTimeoutException 502 /// On timeout throws WorkItemTimeoutException
503 TResult GetResult( 503 TResult GetResult(
504 int millisecondsTimeout, 504 int millisecondsTimeout,
505 bool exitContext, 505 bool exitContext,
506 out Exception e); 506 out Exception e);
507 507
508 /// <summary> 508 /// <summary>
509 /// Get the result of the work item. 509 /// Get the result of the work item.
510 /// If the work item didn't run yet then the caller waits until timeout. 510 /// If the work item didn't run yet then the caller waits until timeout.
511 /// </summary> 511 /// </summary>
512 /// <param name="exitContext"></param> 512 /// <param name="exitContext"></param>
513 /// <param name="e">Filled with the exception if one was thrown</param> 513 /// <param name="e">Filled with the exception if one was thrown</param>
514 /// <param name="timeout"></param> 514 /// <param name="timeout"></param>
515 /// <returns>The result of the work item</returns> 515 /// <returns>The result of the work item</returns>
516 /// On timeout throws WorkItemTimeoutException 516 /// On timeout throws WorkItemTimeoutException
517 TResult GetResult( 517 TResult GetResult(
518 TimeSpan timeout, 518 TimeSpan timeout,
519 bool exitContext, 519 bool exitContext,
520 out Exception e); 520 out Exception e);
521 521
522 /// <summary> 522 /// <summary>
523 /// Get the result of the work item. 523 /// Get the result of the work item.
524 /// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled. 524 /// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
525 /// </summary> 525 /// </summary>
526 /// <param name="millisecondsTimeout">Timeout in milliseconds, or -1 for infinite</param> 526 /// <param name="millisecondsTimeout">Timeout in milliseconds, or -1 for infinite</param>
527 /// <param name="exitContext"> 527 /// <param name="exitContext">
528 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 528 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
529 /// </param> 529 /// </param>
530 /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the blocking if needed</param> 530 /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the blocking if needed</param>
531 /// <param name="e">Filled with the exception if one was thrown</param> 531 /// <param name="e">Filled with the exception if one was thrown</param>
532 /// <returns>The result of the work item</returns> 532 /// <returns>The result of the work item</returns>
533 /// On timeout throws WorkItemTimeoutException 533 /// On timeout throws WorkItemTimeoutException
534 /// On cancel throws WorkItemCancelException 534 /// On cancel throws WorkItemCancelException
535 TResult GetResult( 535 TResult GetResult(
536 int millisecondsTimeout, 536 int millisecondsTimeout,
537 bool exitContext, 537 bool exitContext,
538 WaitHandle cancelWaitHandle, 538 WaitHandle cancelWaitHandle,
539 out Exception e); 539 out Exception e);
540 540
541 /// <summary> 541 /// <summary>
542 /// Get the result of the work item. 542 /// Get the result of the work item.
543 /// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled. 543 /// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
544 /// </summary> 544 /// </summary>
545 /// <returns>The result of the work item</returns> 545 /// <returns>The result of the work item</returns>
546 /// <param name="cancelWaitHandle"></param> 546 /// <param name="cancelWaitHandle"></param>
547 /// <param name="e">Filled with the exception if one was thrown</param> 547 /// <param name="e">Filled with the exception if one was thrown</param>
548 /// <param name="timeout"></param> 548 /// <param name="timeout"></param>
549 /// <param name="exitContext"></param> 549 /// <param name="exitContext"></param>
550 /// On timeout throws WorkItemTimeoutException 550 /// On timeout throws WorkItemTimeoutException
551 /// On cancel throws WorkItemCancelException 551 /// On cancel throws WorkItemCancelException
552 TResult GetResult( 552 TResult GetResult(
553 TimeSpan timeout, 553 TimeSpan timeout,
554 bool exitContext, 554 bool exitContext,
555 WaitHandle cancelWaitHandle, 555 WaitHandle cancelWaitHandle,
556 out Exception e); 556 out Exception e);
557 557
558 /// <summary> 558 /// <summary>
559 /// Gets an indication whether the asynchronous operation has completed. 559 /// Gets an indication whether the asynchronous operation has completed.
560 /// </summary> 560 /// </summary>
561 bool IsCompleted { get; } 561 bool IsCompleted { get; }
562 562
563 /// <summary> 563 /// <summary>
564 /// Gets an indication whether the asynchronous operation has been canceled. 564 /// Gets an indication whether the asynchronous operation has been canceled.
565 /// </summary> 565 /// </summary>
566 bool IsCanceled { get; } 566 bool IsCanceled { get; }
567 567
568 /// <summary> 568 /// <summary>
569 /// Gets the user-defined object that contains context data 569 /// Gets the user-defined object that contains context data
570 /// for the work item method. 570 /// for the work item method.
571 /// </summary> 571 /// </summary>
572 object State { get; } 572 object State { get; }
573 573
574 /// <summary> 574 /// <summary>
575 /// Same as Cancel(false). 575 /// Same as Cancel(false).
576 /// </summary> 576 /// </summary>
577 bool Cancel(); 577 bool Cancel();
578 578
579 /// <summary> 579 /// <summary>
580 /// Cancel the work item execution. 580 /// Cancel the work item execution.
581 /// If the work item is in the queue then it won't execute 581 /// If the work item is in the queue then it won't execute
582 /// If the work item is completed, it will remain completed 582 /// If the work item is completed, it will remain completed
583 /// If the work item is in progress then the user can check the SmartThreadPool.IsWorkItemCanceled 583 /// If the work item is in progress then the user can check the SmartThreadPool.IsWorkItemCanceled
584 /// property to check if the work item has been cancelled. If the abortExecution is set to true then 584 /// property to check if the work item has been cancelled. If the abortExecution is set to true then
585 /// the Smart Thread Pool will send an AbortException to the running thread to stop the execution 585 /// the Smart Thread Pool will send an AbortException to the running thread to stop the execution
586 /// of the work item. When an in progress work item is canceled its GetResult will throw WorkItemCancelException. 586 /// of the work item. When an in progress work item is canceled its GetResult will throw WorkItemCancelException.
587 /// If the work item is already cancelled it will remain cancelled 587 /// If the work item is already cancelled it will remain cancelled
588 /// </summary> 588 /// </summary>
589 /// <param name="abortExecution">When true send an AbortException to the executing thread.</param> 589 /// <param name="abortExecution">When true send an AbortException to the executing thread.</param>
590 /// <returns>Returns true if the work item was not completed, otherwise false.</returns> 590 /// <returns>Returns true if the work item was not completed, otherwise false.</returns>
591 bool Cancel(bool abortExecution); 591 bool Cancel(bool abortExecution);
592 592
593 /// <summary> 593 /// <summary>
594 /// Get the work item's priority 594 /// Get the work item's priority
595 /// </summary> 595 /// </summary>
596 WorkItemPriority WorkItemPriority { get; } 596 WorkItemPriority WorkItemPriority { get; }
597 597
598 /// <summary> 598 /// <summary>
599 /// Return the result, same as GetResult() 599 /// Return the result, same as GetResult()
600 /// </summary> 600 /// </summary>
601 TResult Result { get; } 601 TResult Result { get; }
602 602
603 /// <summary> 603 /// <summary>
604 /// Returns the exception if occured otherwise returns null. 604 /// Returns the exception if occured otherwise returns null.
605 /// </summary> 605 /// </summary>
606 object Exception { get; } 606 object Exception { get; }
607 } 607 }
608 608
609 #endregion 609 #endregion
610 610
611 #region .NET 3.5 611 #region .NET 3.5
612 612
613 // All these delegate are built-in .NET 3.5 613 // All these delegate are built-in .NET 3.5
614 // Comment/Remove them when compiling to .NET 3.5 to avoid ambiguity. 614 // Comment/Remove them when compiling to .NET 3.5 to avoid ambiguity.
615 615
616 public delegate void Action(); 616 public delegate void Action();
617 public delegate void Action<T1, T2>(T1 arg1, T2 arg2); 617 public delegate void Action<T1, T2>(T1 arg1, T2 arg2);
618 public delegate void Action<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3); 618 public delegate void Action<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3);
619 public delegate void Action<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4); 619 public delegate void Action<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
620 620
621 public delegate TResult Func<TResult>(); 621 public delegate TResult Func<TResult>();
622 public delegate TResult Func<T, TResult>(T arg1); 622 public delegate TResult Func<T, TResult>(T arg1);
623 public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2); 623 public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
624 public delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3); 624 public delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
625 public delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4); 625 public delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
626 626
627 #endregion 627 #endregion
628} 628}
diff --git a/ThirdParty/SmartThreadPool/InternalInterfaces.cs b/ThirdParty/SmartThreadPool/InternalInterfaces.cs
index 8be7161..0072e10 100644
--- a/ThirdParty/SmartThreadPool/InternalInterfaces.cs
+++ b/ThirdParty/SmartThreadPool/InternalInterfaces.cs
@@ -1,27 +1,27 @@
1 1
2namespace Amib.Threading.Internal 2namespace Amib.Threading.Internal
3{ 3{
4 /// <summary> 4 /// <summary>
5 /// An internal delegate to call when the WorkItem starts or completes 5 /// An internal delegate to call when the WorkItem starts or completes
6 /// </summary> 6 /// </summary>
7 internal delegate void WorkItemStateCallback(WorkItem workItem); 7 internal delegate void WorkItemStateCallback(WorkItem workItem);
8 8
9 internal interface IInternalWorkItemResult 9 internal interface IInternalWorkItemResult
10 { 10 {
11 event WorkItemStateCallback OnWorkItemStarted; 11 event WorkItemStateCallback OnWorkItemStarted;
12 event WorkItemStateCallback OnWorkItemCompleted; 12 event WorkItemStateCallback OnWorkItemCompleted;
13 } 13 }
14 14
15 internal interface IInternalWaitableResult 15 internal interface IInternalWaitableResult
16 { 16 {
17 /// <summary> 17 /// <summary>
18 /// This method is intent for internal use. 18 /// This method is intent for internal use.
19 /// </summary> 19 /// </summary>
20 IWorkItemResult GetWorkItemResult(); 20 IWorkItemResult GetWorkItemResult();
21 } 21 }
22 22
23 public interface IHasWorkItemPriority 23 public interface IHasWorkItemPriority
24 { 24 {
25 WorkItemPriority WorkItemPriority { get; } 25 WorkItemPriority WorkItemPriority { get; }
26 } 26 }
27} 27}
diff --git a/ThirdParty/SmartThreadPool/PriorityQueue.cs b/ThirdParty/SmartThreadPool/PriorityQueue.cs
index 6245fd8..409c879 100644
--- a/ThirdParty/SmartThreadPool/PriorityQueue.cs
+++ b/ThirdParty/SmartThreadPool/PriorityQueue.cs
@@ -1,239 +1,239 @@
1using System; 1using System;
2using System.Collections; 2using System.Collections;
3using System.Collections.Generic; 3using System.Collections.Generic;
4using System.Diagnostics; 4using System.Diagnostics;
5 5
6namespace Amib.Threading.Internal 6namespace Amib.Threading.Internal
7{ 7{
8 #region PriorityQueue class 8 #region PriorityQueue class
9 9
10 /// <summary> 10 /// <summary>
11 /// PriorityQueue class 11 /// PriorityQueue class
12 /// This class is not thread safe because we use external lock 12 /// This class is not thread safe because we use external lock
13 /// </summary> 13 /// </summary>
14 public sealed class PriorityQueue : IEnumerable 14 public sealed class PriorityQueue : IEnumerable
15 { 15 {
16 #region Private members 16 #region Private members
17 17
18 /// <summary> 18 /// <summary>
19 /// The number of queues, there is one for each type of priority 19 /// The number of queues, there is one for each type of priority
20 /// </summary> 20 /// </summary>
21 private const int _queuesCount = WorkItemPriority.Highest-WorkItemPriority.Lowest+1; 21 private const int _queuesCount = WorkItemPriority.Highest-WorkItemPriority.Lowest+1;
22 22
23 /// <summary> 23 /// <summary>
24 /// Work items queues. There is one for each type of priority 24 /// Work items queues. There is one for each type of priority
25 /// </summary> 25 /// </summary>
26 private readonly LinkedList<IHasWorkItemPriority>[] _queues = new LinkedList<IHasWorkItemPriority>[_queuesCount]; 26 private readonly LinkedList<IHasWorkItemPriority>[] _queues = new LinkedList<IHasWorkItemPriority>[_queuesCount];
27 27
28 /// <summary> 28 /// <summary>
29 /// The total number of work items within the queues 29 /// The total number of work items within the queues
30 /// </summary> 30 /// </summary>
31 private int _workItemsCount; 31 private int _workItemsCount;
32 32
33 /// <summary> 33 /// <summary>
34 /// Use with IEnumerable interface 34 /// Use with IEnumerable interface
35 /// </summary> 35 /// </summary>
36 private int _version; 36 private int _version;
37 37
38 #endregion 38 #endregion
39 39
40 #region Contructor 40 #region Contructor
41 41
42 public PriorityQueue() 42 public PriorityQueue()
43 { 43 {
44 for(int i = 0; i < _queues.Length; ++i) 44 for(int i = 0; i < _queues.Length; ++i)
45 { 45 {
46 _queues[i] = new LinkedList<IHasWorkItemPriority>(); 46 _queues[i] = new LinkedList<IHasWorkItemPriority>();
47 } 47 }
48 } 48 }
49 49
50 #endregion 50 #endregion
51 51
52 #region Methods 52 #region Methods
53 53
54 /// <summary> 54 /// <summary>
55 /// Enqueue a work item. 55 /// Enqueue a work item.
56 /// </summary> 56 /// </summary>
57 /// <param name="workItem">A work item</param> 57 /// <param name="workItem">A work item</param>
58 public void Enqueue(IHasWorkItemPriority workItem) 58 public void Enqueue(IHasWorkItemPriority workItem)
59 { 59 {
60 Debug.Assert(null != workItem); 60 Debug.Assert(null != workItem);
61 61
62 int queueIndex = _queuesCount-(int)workItem.WorkItemPriority-1; 62 int queueIndex = _queuesCount-(int)workItem.WorkItemPriority-1;
63 Debug.Assert(queueIndex >= 0); 63 Debug.Assert(queueIndex >= 0);
64 Debug.Assert(queueIndex < _queuesCount); 64 Debug.Assert(queueIndex < _queuesCount);
65 65
66 _queues[queueIndex].AddLast(workItem); 66 _queues[queueIndex].AddLast(workItem);
67 ++_workItemsCount; 67 ++_workItemsCount;
68 ++_version; 68 ++_version;
69 } 69 }
70 70
71 /// <summary> 71 /// <summary>
72 /// Dequeque a work item. 72 /// Dequeque a work item.
73 /// </summary> 73 /// </summary>
74 /// <returns>Returns the next work item</returns> 74 /// <returns>Returns the next work item</returns>
75 public IHasWorkItemPriority Dequeue() 75 public IHasWorkItemPriority Dequeue()
76 { 76 {
77 IHasWorkItemPriority workItem = null; 77 IHasWorkItemPriority workItem = null;
78 78
79 if(_workItemsCount > 0) 79 if(_workItemsCount > 0)
80 { 80 {
81 int queueIndex = GetNextNonEmptyQueue(-1); 81 int queueIndex = GetNextNonEmptyQueue(-1);
82 Debug.Assert(queueIndex >= 0); 82 Debug.Assert(queueIndex >= 0);
83 workItem = _queues[queueIndex].First.Value; 83 workItem = _queues[queueIndex].First.Value;
84 _queues[queueIndex].RemoveFirst(); 84 _queues[queueIndex].RemoveFirst();
85 Debug.Assert(null != workItem); 85 Debug.Assert(null != workItem);
86 --_workItemsCount; 86 --_workItemsCount;
87 ++_version; 87 ++_version;
88 } 88 }
89 89
90 return workItem; 90 return workItem;
91 } 91 }
92 92
93 /// <summary> 93 /// <summary>
94 /// Find the next non empty queue starting at queue queueIndex+1 94 /// Find the next non empty queue starting at queue queueIndex+1
95 /// </summary> 95 /// </summary>
96 /// <param name="queueIndex">The index-1 to start from</param> 96 /// <param name="queueIndex">The index-1 to start from</param>
97 /// <returns> 97 /// <returns>
98 /// The index of the next non empty queue or -1 if all the queues are empty 98 /// The index of the next non empty queue or -1 if all the queues are empty
99 /// </returns> 99 /// </returns>
100 private int GetNextNonEmptyQueue(int queueIndex) 100 private int GetNextNonEmptyQueue(int queueIndex)
101 { 101 {
102 for(int i = queueIndex+1; i < _queuesCount; ++i) 102 for(int i = queueIndex+1; i < _queuesCount; ++i)
103 { 103 {
104 if(_queues[i].Count > 0) 104 if(_queues[i].Count > 0)
105 { 105 {
106 return i; 106 return i;
107 } 107 }
108 } 108 }
109 return -1; 109 return -1;
110 } 110 }
111 111
112 /// <summary> 112 /// <summary>
113 /// The number of work items 113 /// The number of work items
114 /// </summary> 114 /// </summary>
115 public int Count 115 public int Count
116 { 116 {
117 get 117 get
118 { 118 {
119 return _workItemsCount; 119 return _workItemsCount;
120 } 120 }
121 } 121 }
122 122
123 /// <summary> 123 /// <summary>
124 /// Clear all the work items 124 /// Clear all the work items
125 /// </summary> 125 /// </summary>
126 public void Clear() 126 public void Clear()
127 { 127 {
128 if (_workItemsCount > 0) 128 if (_workItemsCount > 0)
129 { 129 {
130 foreach(LinkedList<IHasWorkItemPriority> queue in _queues) 130 foreach(LinkedList<IHasWorkItemPriority> queue in _queues)
131 { 131 {
132 queue.Clear(); 132 queue.Clear();
133 } 133 }
134 _workItemsCount = 0; 134 _workItemsCount = 0;
135 ++_version; 135 ++_version;
136 } 136 }
137 } 137 }
138 138
139 #endregion 139 #endregion
140 140
141 #region IEnumerable Members 141 #region IEnumerable Members
142 142
143 /// <summary> 143 /// <summary>
144 /// Returns an enumerator to iterate over the work items 144 /// Returns an enumerator to iterate over the work items
145 /// </summary> 145 /// </summary>
146 /// <returns>Returns an enumerator</returns> 146 /// <returns>Returns an enumerator</returns>
147 public IEnumerator GetEnumerator() 147 public IEnumerator GetEnumerator()
148 { 148 {
149 return new PriorityQueueEnumerator(this); 149 return new PriorityQueueEnumerator(this);
150 } 150 }
151 151
152 #endregion 152 #endregion
153 153
154 #region PriorityQueueEnumerator 154 #region PriorityQueueEnumerator
155 155
156 /// <summary> 156 /// <summary>
157 /// The class the implements the enumerator 157 /// The class the implements the enumerator
158 /// </summary> 158 /// </summary>
159 private class PriorityQueueEnumerator : IEnumerator 159 private class PriorityQueueEnumerator : IEnumerator
160 { 160 {
161 private readonly PriorityQueue _priorityQueue; 161 private readonly PriorityQueue _priorityQueue;
162 private int _version; 162 private int _version;
163 private int _queueIndex; 163 private int _queueIndex;
164 private IEnumerator _enumerator; 164 private IEnumerator _enumerator;
165 165
166 public PriorityQueueEnumerator(PriorityQueue priorityQueue) 166 public PriorityQueueEnumerator(PriorityQueue priorityQueue)
167 { 167 {
168 _priorityQueue = priorityQueue; 168 _priorityQueue = priorityQueue;
169 _version = _priorityQueue._version; 169 _version = _priorityQueue._version;
170 _queueIndex = _priorityQueue.GetNextNonEmptyQueue(-1); 170 _queueIndex = _priorityQueue.GetNextNonEmptyQueue(-1);
171 if (_queueIndex >= 0) 171 if (_queueIndex >= 0)
172 { 172 {
173 _enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator(); 173 _enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator();
174 } 174 }
175 else 175 else
176 { 176 {
177 _enumerator = null; 177 _enumerator = null;
178 } 178 }
179 } 179 }
180 180
181 #region IEnumerator Members 181 #region IEnumerator Members
182 182
183 public void Reset() 183 public void Reset()
184 { 184 {
185 _version = _priorityQueue._version; 185 _version = _priorityQueue._version;
186 _queueIndex = _priorityQueue.GetNextNonEmptyQueue(-1); 186 _queueIndex = _priorityQueue.GetNextNonEmptyQueue(-1);
187 if (_queueIndex >= 0) 187 if (_queueIndex >= 0)
188 { 188 {
189 _enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator(); 189 _enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator();
190 } 190 }
191 else 191 else
192 { 192 {
193 _enumerator = null; 193 _enumerator = null;
194 } 194 }
195 } 195 }
196 196
197 public object Current 197 public object Current
198 { 198 {
199 get 199 get
200 { 200 {
201 Debug.Assert(null != _enumerator); 201 Debug.Assert(null != _enumerator);
202 return _enumerator.Current; 202 return _enumerator.Current;
203 } 203 }
204 } 204 }
205 205
206 public bool MoveNext() 206 public bool MoveNext()
207 { 207 {
208 if (null == _enumerator) 208 if (null == _enumerator)
209 { 209 {
210 return false; 210 return false;
211 } 211 }
212 212
213 if(_version != _priorityQueue._version) 213 if(_version != _priorityQueue._version)
214 { 214 {
215 throw new InvalidOperationException("The collection has been modified"); 215 throw new InvalidOperationException("The collection has been modified");
216 216
217 } 217 }
218 if (!_enumerator.MoveNext()) 218 if (!_enumerator.MoveNext())
219 { 219 {
220 _queueIndex = _priorityQueue.GetNextNonEmptyQueue(_queueIndex); 220 _queueIndex = _priorityQueue.GetNextNonEmptyQueue(_queueIndex);
221 if(-1 == _queueIndex) 221 if(-1 == _queueIndex)
222 { 222 {
223 return false; 223 return false;
224 } 224 }
225 _enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator(); 225 _enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator();
226 _enumerator.MoveNext(); 226 _enumerator.MoveNext();
227 return true; 227 return true;
228 } 228 }
229 return true; 229 return true;
230 } 230 }
231 231
232 #endregion 232 #endregion
233 } 233 }
234 234
235 #endregion 235 #endregion
236 } 236 }
237 237
238 #endregion 238 #endregion
239} 239}
diff --git a/ThirdParty/SmartThreadPool/Properties/AssemblyInfo.cs b/ThirdParty/SmartThreadPool/Properties/AssemblyInfo.cs
index 1651e78..4728c1f 100644
--- a/ThirdParty/SmartThreadPool/Properties/AssemblyInfo.cs
+++ b/ThirdParty/SmartThreadPool/Properties/AssemblyInfo.cs
@@ -1,23 +1,23 @@
1using System.Reflection; 1using System.Reflection;
2using System.Runtime.CompilerServices; 2using System.Runtime.CompilerServices;
3using System.Runtime.InteropServices; 3using System.Runtime.InteropServices;
4 4
5[assembly: AssemblyTitle("Amib.Threading")] 5[assembly: AssemblyTitle("Amib.Threading")]
6[assembly: AssemblyDescription("Smart Thread Pool")] 6[assembly: AssemblyDescription("Smart Thread Pool")]
7[assembly: AssemblyConfiguration("")] 7[assembly: AssemblyConfiguration("")]
8[assembly: AssemblyCompany("")] 8[assembly: AssemblyCompany("")]
9[assembly: AssemblyProduct("Amib.Threading")] 9[assembly: AssemblyProduct("Amib.Threading")]
10[assembly: AssemblyCopyright("")] 10[assembly: AssemblyCopyright("")]
11[assembly: AssemblyTrademark("")] 11[assembly: AssemblyTrademark("")]
12[assembly: AssemblyCulture("")] 12[assembly: AssemblyCulture("")]
13[assembly: ComVisible(false)] 13[assembly: ComVisible(false)]
14[assembly: Guid("c764a3de-c4f8-434d-85b5-a09830d1e44f")] 14[assembly: Guid("c764a3de-c4f8-434d-85b5-a09830d1e44f")]
15[assembly: AssemblyVersion("2.2.3.0")] 15[assembly: AssemblyVersion("2.2.3.0")]
16 16
17#if (_PUBLISH) 17#if (_PUBLISH)
18[assembly: InternalsVisibleTo("STPTests,PublicKey=00240000048000009400000006020000002400005253413100040000010001004fe3d39add741ba7c8d52cd1eb0d94c7d79060ad956cbaff0e51c1dce94db10356b261778bc1ac3114b3218434da6fcd8416dd5507653809598f7d2afc422099ce4f6b7b0477f18e6c57c727ef2a7ab6ee56e6b4589fe44cb0e25f2875a3c65ab0383ee33c4dd93023f7ce1218bebc8b7a9a1dac878938f5c4f45ea74b6bd8ad")] 18[assembly: InternalsVisibleTo("STPTests,PublicKey=00240000048000009400000006020000002400005253413100040000010001004fe3d39add741ba7c8d52cd1eb0d94c7d79060ad956cbaff0e51c1dce94db10356b261778bc1ac3114b3218434da6fcd8416dd5507653809598f7d2afc422099ce4f6b7b0477f18e6c57c727ef2a7ab6ee56e6b4589fe44cb0e25f2875a3c65ab0383ee33c4dd93023f7ce1218bebc8b7a9a1dac878938f5c4f45ea74b6bd8ad")]
19#else 19#else
20[assembly: InternalsVisibleTo("STPTests")] 20[assembly: InternalsVisibleTo("STPTests")]
21#endif 21#endif
22 22
23 23
diff --git a/ThirdParty/SmartThreadPool/SLExt.cs b/ThirdParty/SmartThreadPool/SLExt.cs
index fafff19..23a60bc 100644
--- a/ThirdParty/SmartThreadPool/SLExt.cs
+++ b/ThirdParty/SmartThreadPool/SLExt.cs
@@ -1,16 +1,16 @@
1#if _SILVERLIGHT 1#if _SILVERLIGHT
2 2
3using System.Threading; 3using System.Threading;
4 4
5namespace Amib.Threading 5namespace Amib.Threading
6{ 6{
7 public enum ThreadPriority 7 public enum ThreadPriority
8 { 8 {
9 Lowest, 9 Lowest,
10 BelowNormal, 10 BelowNormal,
11 Normal, 11 Normal,
12 AboveNormal, 12 AboveNormal,
13 Highest, 13 Highest,
14 } 14 }
15} 15}
16#endif 16#endif
diff --git a/ThirdParty/SmartThreadPool/STPEventWaitHandle.cs b/ThirdParty/SmartThreadPool/STPEventWaitHandle.cs
index 3b92645..9b17f69 100644
--- a/ThirdParty/SmartThreadPool/STPEventWaitHandle.cs
+++ b/ThirdParty/SmartThreadPool/STPEventWaitHandle.cs
@@ -1,62 +1,62 @@
1#if !(_WINDOWS_CE) 1#if !(_WINDOWS_CE)
2 2
3using System; 3using System;
4using System.Threading; 4using System.Threading;
5 5
6namespace Amib.Threading.Internal 6namespace Amib.Threading.Internal
7{ 7{
8#if _WINDOWS || WINDOWS_PHONE 8#if _WINDOWS || WINDOWS_PHONE
9 internal static class STPEventWaitHandle 9 internal static class STPEventWaitHandle
10 { 10 {
11 public const int WaitTimeout = Timeout.Infinite; 11 public const int WaitTimeout = Timeout.Infinite;
12 12
13 internal static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext) 13 internal static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
14 { 14 {
15 return WaitHandle.WaitAll(waitHandles, millisecondsTimeout); 15 return WaitHandle.WaitAll(waitHandles, millisecondsTimeout);
16 } 16 }
17 17
18 internal static int WaitAny(WaitHandle[] waitHandles) 18 internal static int WaitAny(WaitHandle[] waitHandles)
19 { 19 {
20 return WaitHandle.WaitAny(waitHandles); 20 return WaitHandle.WaitAny(waitHandles);
21 } 21 }
22 22
23 internal static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext) 23 internal static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
24 { 24 {
25 return WaitHandle.WaitAny(waitHandles, millisecondsTimeout); 25 return WaitHandle.WaitAny(waitHandles, millisecondsTimeout);
26 } 26 }
27 27
28 internal static bool WaitOne(WaitHandle waitHandle, int millisecondsTimeout, bool exitContext) 28 internal static bool WaitOne(WaitHandle waitHandle, int millisecondsTimeout, bool exitContext)
29 { 29 {
30 return waitHandle.WaitOne(millisecondsTimeout); 30 return waitHandle.WaitOne(millisecondsTimeout);
31 } 31 }
32 } 32 }
33#else 33#else
34 internal static class STPEventWaitHandle 34 internal static class STPEventWaitHandle
35 { 35 {
36 public const int WaitTimeout = Timeout.Infinite; 36 public const int WaitTimeout = Timeout.Infinite;
37 37
38 internal static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext) 38 internal static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
39 { 39 {
40 return WaitHandle.WaitAll(waitHandles, millisecondsTimeout, exitContext); 40 return WaitHandle.WaitAll(waitHandles, millisecondsTimeout, exitContext);
41 } 41 }
42 42
43 internal static int WaitAny(WaitHandle[] waitHandles) 43 internal static int WaitAny(WaitHandle[] waitHandles)
44 { 44 {
45 return WaitHandle.WaitAny(waitHandles); 45 return WaitHandle.WaitAny(waitHandles);
46 } 46 }
47 47
48 internal static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext) 48 internal static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
49 { 49 {
50 return WaitHandle.WaitAny(waitHandles, millisecondsTimeout, exitContext); 50 return WaitHandle.WaitAny(waitHandles, millisecondsTimeout, exitContext);
51 } 51 }
52 52
53 internal static bool WaitOne(WaitHandle waitHandle, int millisecondsTimeout, bool exitContext) 53 internal static bool WaitOne(WaitHandle waitHandle, int millisecondsTimeout, bool exitContext)
54 { 54 {
55 return waitHandle.WaitOne(millisecondsTimeout, exitContext); 55 return waitHandle.WaitOne(millisecondsTimeout, exitContext);
56 } 56 }
57 } 57 }
58#endif 58#endif
59 59
60} 60}
61 61
62#endif \ No newline at end of file 62#endif \ No newline at end of file
diff --git a/ThirdParty/SmartThreadPool/STPPerformanceCounter.cs b/ThirdParty/SmartThreadPool/STPPerformanceCounter.cs
index 2508661..0663d1d 100644
--- a/ThirdParty/SmartThreadPool/STPPerformanceCounter.cs
+++ b/ThirdParty/SmartThreadPool/STPPerformanceCounter.cs
@@ -1,448 +1,448 @@
1using System; 1using System;
2using System.Diagnostics; 2using System.Diagnostics;
3using System.Threading; 3using System.Threading;
4 4
5namespace Amib.Threading 5namespace Amib.Threading
6{ 6{
7 public interface ISTPPerformanceCountersReader 7 public interface ISTPPerformanceCountersReader
8 { 8 {
9 long InUseThreads { get; } 9 long InUseThreads { get; }
10 long ActiveThreads { get; } 10 long ActiveThreads { get; }
11 long WorkItemsQueued { get; } 11 long WorkItemsQueued { get; }
12 long WorkItemsProcessed { get; } 12 long WorkItemsProcessed { get; }
13 } 13 }
14} 14}
15 15
16namespace Amib.Threading.Internal 16namespace Amib.Threading.Internal
17{ 17{
18 internal interface ISTPInstancePerformanceCounters : IDisposable 18 internal interface ISTPInstancePerformanceCounters : IDisposable
19 { 19 {
20 void Close(); 20 void Close();
21 void SampleThreads(long activeThreads, long inUseThreads); 21 void SampleThreads(long activeThreads, long inUseThreads);
22 void SampleWorkItems(long workItemsQueued, long workItemsProcessed); 22 void SampleWorkItems(long workItemsQueued, long workItemsProcessed);
23 void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime); 23 void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime);
24 void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime); 24 void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime);
25 } 25 }
26#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE) 26#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
27 27
28 internal enum STPPerformanceCounterType 28 internal enum STPPerformanceCounterType
29 { 29 {
30 // Fields 30 // Fields
31 ActiveThreads = 0, 31 ActiveThreads = 0,
32 InUseThreads = 1, 32 InUseThreads = 1,
33 OverheadThreads = 2, 33 OverheadThreads = 2,
34 OverheadThreadsPercent = 3, 34 OverheadThreadsPercent = 3,
35 OverheadThreadsPercentBase = 4, 35 OverheadThreadsPercentBase = 4,
36 36
37 WorkItems = 5, 37 WorkItems = 5,
38 WorkItemsInQueue = 6, 38 WorkItemsInQueue = 6,
39 WorkItemsProcessed = 7, 39 WorkItemsProcessed = 7,
40 40
41 WorkItemsQueuedPerSecond = 8, 41 WorkItemsQueuedPerSecond = 8,
42 WorkItemsProcessedPerSecond = 9, 42 WorkItemsProcessedPerSecond = 9,
43 43
44 AvgWorkItemWaitTime = 10, 44 AvgWorkItemWaitTime = 10,
45 AvgWorkItemWaitTimeBase = 11, 45 AvgWorkItemWaitTimeBase = 11,
46 46
47 AvgWorkItemProcessTime = 12, 47 AvgWorkItemProcessTime = 12,
48 AvgWorkItemProcessTimeBase = 13, 48 AvgWorkItemProcessTimeBase = 13,
49 49
50 WorkItemsGroups = 14, 50 WorkItemsGroups = 14,
51 51
52 LastCounter = 14, 52 LastCounter = 14,
53 } 53 }
54 54
55 55
56 /// <summary> 56 /// <summary>
57 /// Summary description for STPPerformanceCounter. 57 /// Summary description for STPPerformanceCounter.
58 /// </summary> 58 /// </summary>
59 internal class STPPerformanceCounter 59 internal class STPPerformanceCounter
60 { 60 {
61 // Fields 61 // Fields
62 private readonly PerformanceCounterType _pcType; 62 private readonly PerformanceCounterType _pcType;
63 protected string _counterHelp; 63 protected string _counterHelp;
64 protected string _counterName; 64 protected string _counterName;
65 65
66 // Methods 66 // Methods
67 public STPPerformanceCounter( 67 public STPPerformanceCounter(
68 string counterName, 68 string counterName,
69 string counterHelp, 69 string counterHelp,
70 PerformanceCounterType pcType) 70 PerformanceCounterType pcType)
71 { 71 {
72 _counterName = counterName; 72 _counterName = counterName;
73 _counterHelp = counterHelp; 73 _counterHelp = counterHelp;
74 _pcType = pcType; 74 _pcType = pcType;
75 } 75 }
76 76
77 public void AddCounterToCollection(CounterCreationDataCollection counterData) 77 public void AddCounterToCollection(CounterCreationDataCollection counterData)
78 { 78 {
79 CounterCreationData counterCreationData = new CounterCreationData( 79 CounterCreationData counterCreationData = new CounterCreationData(
80 _counterName, 80 _counterName,
81 _counterHelp, 81 _counterHelp,
82 _pcType); 82 _pcType);
83 83
84 counterData.Add(counterCreationData); 84 counterData.Add(counterCreationData);
85 } 85 }
86 86
87 // Properties 87 // Properties
88 public string Name 88 public string Name
89 { 89 {
90 get 90 get
91 { 91 {
92 return _counterName; 92 return _counterName;
93 } 93 }
94 } 94 }
95 } 95 }
96 96
97 internal class STPPerformanceCounters 97 internal class STPPerformanceCounters
98 { 98 {
99 // Fields 99 // Fields
100 internal STPPerformanceCounter[] _stpPerformanceCounters; 100 internal STPPerformanceCounter[] _stpPerformanceCounters;
101 private static readonly STPPerformanceCounters _instance; 101 private static readonly STPPerformanceCounters _instance;
102 internal const string _stpCategoryHelp = "SmartThreadPool performance counters"; 102 internal const string _stpCategoryHelp = "SmartThreadPool performance counters";
103 internal const string _stpCategoryName = "SmartThreadPool"; 103 internal const string _stpCategoryName = "SmartThreadPool";
104 104
105 // Methods 105 // Methods
106 static STPPerformanceCounters() 106 static STPPerformanceCounters()
107 { 107 {
108 _instance = new STPPerformanceCounters(); 108 _instance = new STPPerformanceCounters();
109 } 109 }
110 110
111 private STPPerformanceCounters() 111 private STPPerformanceCounters()
112 { 112 {
113 STPPerformanceCounter[] stpPerformanceCounters = new STPPerformanceCounter[] 113 STPPerformanceCounter[] stpPerformanceCounters = new STPPerformanceCounter[]
114 { 114 {
115 new STPPerformanceCounter("Active threads", "The current number of available in the thread pool.", PerformanceCounterType.NumberOfItems32), 115 new STPPerformanceCounter("Active threads", "The current number of available in the thread pool.", PerformanceCounterType.NumberOfItems32),
116 new STPPerformanceCounter("In use threads", "The current number of threads that execute a work item.", PerformanceCounterType.NumberOfItems32), 116 new STPPerformanceCounter("In use threads", "The current number of threads that execute a work item.", PerformanceCounterType.NumberOfItems32),
117 new STPPerformanceCounter("Overhead threads", "The current number of threads that are active, but are not in use.", PerformanceCounterType.NumberOfItems32), 117 new STPPerformanceCounter("Overhead threads", "The current number of threads that are active, but are not in use.", PerformanceCounterType.NumberOfItems32),
118 new STPPerformanceCounter("% overhead threads", "The current number of threads that are active, but are not in use in percents.", PerformanceCounterType.RawFraction), 118 new STPPerformanceCounter("% overhead threads", "The current number of threads that are active, but are not in use in percents.", PerformanceCounterType.RawFraction),
119 new STPPerformanceCounter("% overhead threads base", "The current number of threads that are active, but are not in use in percents.", PerformanceCounterType.RawBase), 119 new STPPerformanceCounter("% overhead threads base", "The current number of threads that are active, but are not in use in percents.", PerformanceCounterType.RawBase),
120 120
121 new STPPerformanceCounter("Work Items", "The number of work items in the Smart Thread Pool. Both queued and processed.", PerformanceCounterType.NumberOfItems32), 121 new STPPerformanceCounter("Work Items", "The number of work items in the Smart Thread Pool. Both queued and processed.", PerformanceCounterType.NumberOfItems32),
122 new STPPerformanceCounter("Work Items in queue", "The current number of work items in the queue", PerformanceCounterType.NumberOfItems32), 122 new STPPerformanceCounter("Work Items in queue", "The current number of work items in the queue", PerformanceCounterType.NumberOfItems32),
123 new STPPerformanceCounter("Work Items processed", "The number of work items already processed", PerformanceCounterType.NumberOfItems32), 123 new STPPerformanceCounter("Work Items processed", "The number of work items already processed", PerformanceCounterType.NumberOfItems32),
124 124
125 new STPPerformanceCounter("Work Items queued/sec", "The number of work items queued per second", PerformanceCounterType.RateOfCountsPerSecond32), 125 new STPPerformanceCounter("Work Items queued/sec", "The number of work items queued per second", PerformanceCounterType.RateOfCountsPerSecond32),
126 new STPPerformanceCounter("Work Items processed/sec", "The number of work items processed per second", PerformanceCounterType.RateOfCountsPerSecond32), 126 new STPPerformanceCounter("Work Items processed/sec", "The number of work items processed per second", PerformanceCounterType.RateOfCountsPerSecond32),
127 127
128 new STPPerformanceCounter("Avg. Work Item wait time/sec", "The average time a work item supends in the queue waiting for its turn to execute.", PerformanceCounterType.AverageCount64), 128 new STPPerformanceCounter("Avg. Work Item wait time/sec", "The average time a work item supends in the queue waiting for its turn to execute.", PerformanceCounterType.AverageCount64),
129 new STPPerformanceCounter("Avg. Work Item wait time base", "The average time a work item supends in the queue waiting for its turn to execute.", PerformanceCounterType.AverageBase), 129 new STPPerformanceCounter("Avg. Work Item wait time base", "The average time a work item supends in the queue waiting for its turn to execute.", PerformanceCounterType.AverageBase),
130 130
131 new STPPerformanceCounter("Avg. Work Item process time/sec", "The average time it takes to process a work item.", PerformanceCounterType.AverageCount64), 131 new STPPerformanceCounter("Avg. Work Item process time/sec", "The average time it takes to process a work item.", PerformanceCounterType.AverageCount64),
132 new STPPerformanceCounter("Avg. Work Item process time base", "The average time it takes to process a work item.", PerformanceCounterType.AverageBase), 132 new STPPerformanceCounter("Avg. Work Item process time base", "The average time it takes to process a work item.", PerformanceCounterType.AverageBase),
133 133
134 new STPPerformanceCounter("Work Items Groups", "The current number of work item groups associated with the Smart Thread Pool.", PerformanceCounterType.NumberOfItems32), 134 new STPPerformanceCounter("Work Items Groups", "The current number of work item groups associated with the Smart Thread Pool.", PerformanceCounterType.NumberOfItems32),
135 }; 135 };
136 136
137 _stpPerformanceCounters = stpPerformanceCounters; 137 _stpPerformanceCounters = stpPerformanceCounters;
138 SetupCategory(); 138 SetupCategory();
139 } 139 }
140 140
141 private void SetupCategory() 141 private void SetupCategory()
142 { 142 {
143 if (!PerformanceCounterCategory.Exists(_stpCategoryName)) 143 if (!PerformanceCounterCategory.Exists(_stpCategoryName))
144 { 144 {
145 CounterCreationDataCollection counters = new CounterCreationDataCollection(); 145 CounterCreationDataCollection counters = new CounterCreationDataCollection();
146 146
147 for (int i = 0; i < _stpPerformanceCounters.Length; i++) 147 for (int i = 0; i < _stpPerformanceCounters.Length; i++)
148 { 148 {
149 _stpPerformanceCounters[i].AddCounterToCollection(counters); 149 _stpPerformanceCounters[i].AddCounterToCollection(counters);
150 } 150 }
151 151
152 PerformanceCounterCategory.Create( 152 PerformanceCounterCategory.Create(
153 _stpCategoryName, 153 _stpCategoryName,
154 _stpCategoryHelp, 154 _stpCategoryHelp,
155 PerformanceCounterCategoryType.MultiInstance, 155 PerformanceCounterCategoryType.MultiInstance,
156 counters); 156 counters);
157 157
158 } 158 }
159 } 159 }
160 160
161 // Properties 161 // Properties
162 public static STPPerformanceCounters Instance 162 public static STPPerformanceCounters Instance
163 { 163 {
164 get 164 get
165 { 165 {
166 return _instance; 166 return _instance;
167 } 167 }
168 } 168 }
169 } 169 }
170 170
171 internal class STPInstancePerformanceCounter : IDisposable 171 internal class STPInstancePerformanceCounter : IDisposable
172 { 172 {
173 // Fields 173 // Fields
174 private bool _isDisposed; 174 private bool _isDisposed;
175 private PerformanceCounter _pcs; 175 private PerformanceCounter _pcs;
176 176
177 // Methods 177 // Methods
178 protected STPInstancePerformanceCounter() 178 protected STPInstancePerformanceCounter()
179 { 179 {
180 _isDisposed = false; 180 _isDisposed = false;
181 } 181 }
182 182
183 public STPInstancePerformanceCounter( 183 public STPInstancePerformanceCounter(
184 string instance, 184 string instance,
185 STPPerformanceCounterType spcType) : this() 185 STPPerformanceCounterType spcType) : this()
186 { 186 {
187 STPPerformanceCounters counters = STPPerformanceCounters.Instance; 187 STPPerformanceCounters counters = STPPerformanceCounters.Instance;
188 _pcs = new PerformanceCounter( 188 _pcs = new PerformanceCounter(
189 STPPerformanceCounters._stpCategoryName, 189 STPPerformanceCounters._stpCategoryName,
190 counters._stpPerformanceCounters[(int) spcType].Name, 190 counters._stpPerformanceCounters[(int) spcType].Name,
191 instance, 191 instance,
192 false); 192 false);
193 _pcs.RawValue = _pcs.RawValue; 193 _pcs.RawValue = _pcs.RawValue;
194 } 194 }
195 195
196 196
197 public void Close() 197 public void Close()
198 { 198 {
199 if (_pcs != null) 199 if (_pcs != null)
200 { 200 {
201 _pcs.RemoveInstance(); 201 _pcs.RemoveInstance();
202 _pcs.Close(); 202 _pcs.Close();
203 _pcs = null; 203 _pcs = null;
204 } 204 }
205 } 205 }
206 206
207 public void Dispose() 207 public void Dispose()
208 { 208 {
209 Dispose(true); 209 Dispose(true);
210 } 210 }
211 211
212 public virtual void Dispose(bool disposing) 212 public virtual void Dispose(bool disposing)
213 { 213 {
214 if (!_isDisposed) 214 if (!_isDisposed)
215 { 215 {
216 if (disposing) 216 if (disposing)
217 { 217 {
218 Close(); 218 Close();
219 } 219 }
220 } 220 }
221 _isDisposed = true; 221 _isDisposed = true;
222 } 222 }
223 223
224 public virtual void Increment() 224 public virtual void Increment()
225 { 225 {
226 _pcs.Increment(); 226 _pcs.Increment();
227 } 227 }
228 228
229 public virtual void IncrementBy(long val) 229 public virtual void IncrementBy(long val)
230 { 230 {
231 _pcs.IncrementBy(val); 231 _pcs.IncrementBy(val);
232 } 232 }
233 233
234 public virtual void Set(long val) 234 public virtual void Set(long val)
235 { 235 {
236 _pcs.RawValue = val; 236 _pcs.RawValue = val;
237 } 237 }
238 } 238 }
239 239
240 internal class STPInstanceNullPerformanceCounter : STPInstancePerformanceCounter 240 internal class STPInstanceNullPerformanceCounter : STPInstancePerformanceCounter
241 { 241 {
242 // Methods 242 // Methods
243 public override void Increment() {} 243 public override void Increment() {}
244 public override void IncrementBy(long value) {} 244 public override void IncrementBy(long value) {}
245 public override void Set(long val) {} 245 public override void Set(long val) {}
246 } 246 }
247 247
248 248
249 249
250 internal class STPInstancePerformanceCounters : ISTPInstancePerformanceCounters 250 internal class STPInstancePerformanceCounters : ISTPInstancePerformanceCounters
251 { 251 {
252 private bool _isDisposed; 252 private bool _isDisposed;
253 // Fields 253 // Fields
254 private STPInstancePerformanceCounter[] _pcs; 254 private STPInstancePerformanceCounter[] _pcs;
255 private static readonly STPInstancePerformanceCounter _stpInstanceNullPerformanceCounter; 255 private static readonly STPInstancePerformanceCounter _stpInstanceNullPerformanceCounter;
256 256
257 // Methods 257 // Methods
258 static STPInstancePerformanceCounters() 258 static STPInstancePerformanceCounters()
259 { 259 {
260 _stpInstanceNullPerformanceCounter = new STPInstanceNullPerformanceCounter(); 260 _stpInstanceNullPerformanceCounter = new STPInstanceNullPerformanceCounter();
261 } 261 }
262 262
263 public STPInstancePerformanceCounters(string instance) 263 public STPInstancePerformanceCounters(string instance)
264 { 264 {
265 _isDisposed = false; 265 _isDisposed = false;
266 _pcs = new STPInstancePerformanceCounter[(int)STPPerformanceCounterType.LastCounter]; 266 _pcs = new STPInstancePerformanceCounter[(int)STPPerformanceCounterType.LastCounter];
267 267
268 // Call the STPPerformanceCounters.Instance so the static constructor will 268 // Call the STPPerformanceCounters.Instance so the static constructor will
269 // intialize the STPPerformanceCounters singleton. 269 // intialize the STPPerformanceCounters singleton.
270 STPPerformanceCounters.Instance.GetHashCode(); 270 STPPerformanceCounters.Instance.GetHashCode();
271 271
272 for (int i = 0; i < _pcs.Length; i++) 272 for (int i = 0; i < _pcs.Length; i++)
273 { 273 {
274 if (instance != null) 274 if (instance != null)
275 { 275 {
276 _pcs[i] = new STPInstancePerformanceCounter( 276 _pcs[i] = new STPInstancePerformanceCounter(
277 instance, 277 instance,
278 (STPPerformanceCounterType) i); 278 (STPPerformanceCounterType) i);
279 } 279 }
280 else 280 else
281 { 281 {
282 _pcs[i] = _stpInstanceNullPerformanceCounter; 282 _pcs[i] = _stpInstanceNullPerformanceCounter;
283 } 283 }
284 } 284 }
285 } 285 }
286 286
287 287
288 public void Close() 288 public void Close()
289 { 289 {
290 if (null != _pcs) 290 if (null != _pcs)
291 { 291 {
292 for (int i = 0; i < _pcs.Length; i++) 292 for (int i = 0; i < _pcs.Length; i++)
293 { 293 {
294 if (null != _pcs[i]) 294 if (null != _pcs[i])
295 { 295 {
296 _pcs[i].Dispose(); 296 _pcs[i].Dispose();
297 } 297 }
298 } 298 }
299 _pcs = null; 299 _pcs = null;
300 } 300 }
301 } 301 }
302 302
303 public void Dispose() 303 public void Dispose()
304 { 304 {
305 Dispose(true); 305 Dispose(true);
306 } 306 }
307 307
308 public virtual void Dispose(bool disposing) 308 public virtual void Dispose(bool disposing)
309 { 309 {
310 if (!_isDisposed) 310 if (!_isDisposed)
311 { 311 {
312 if (disposing) 312 if (disposing)
313 { 313 {
314 Close(); 314 Close();
315 } 315 }
316 } 316 }
317 _isDisposed = true; 317 _isDisposed = true;
318 } 318 }
319 319
320 private STPInstancePerformanceCounter GetCounter(STPPerformanceCounterType spcType) 320 private STPInstancePerformanceCounter GetCounter(STPPerformanceCounterType spcType)
321 { 321 {
322 return _pcs[(int) spcType]; 322 return _pcs[(int) spcType];
323 } 323 }
324 324
325 public void SampleThreads(long activeThreads, long inUseThreads) 325 public void SampleThreads(long activeThreads, long inUseThreads)
326 { 326 {
327 GetCounter(STPPerformanceCounterType.ActiveThreads).Set(activeThreads); 327 GetCounter(STPPerformanceCounterType.ActiveThreads).Set(activeThreads);
328 GetCounter(STPPerformanceCounterType.InUseThreads).Set(inUseThreads); 328 GetCounter(STPPerformanceCounterType.InUseThreads).Set(inUseThreads);
329 GetCounter(STPPerformanceCounterType.OverheadThreads).Set(activeThreads-inUseThreads); 329 GetCounter(STPPerformanceCounterType.OverheadThreads).Set(activeThreads-inUseThreads);
330 330
331 GetCounter(STPPerformanceCounterType.OverheadThreadsPercentBase).Set(activeThreads-inUseThreads); 331 GetCounter(STPPerformanceCounterType.OverheadThreadsPercentBase).Set(activeThreads-inUseThreads);
332 GetCounter(STPPerformanceCounterType.OverheadThreadsPercent).Set(inUseThreads); 332 GetCounter(STPPerformanceCounterType.OverheadThreadsPercent).Set(inUseThreads);
333 } 333 }
334 334
335 public void SampleWorkItems(long workItemsQueued, long workItemsProcessed) 335 public void SampleWorkItems(long workItemsQueued, long workItemsProcessed)
336 { 336 {
337 GetCounter(STPPerformanceCounterType.WorkItems).Set(workItemsQueued+workItemsProcessed); 337 GetCounter(STPPerformanceCounterType.WorkItems).Set(workItemsQueued+workItemsProcessed);
338 GetCounter(STPPerformanceCounterType.WorkItemsInQueue).Set(workItemsQueued); 338 GetCounter(STPPerformanceCounterType.WorkItemsInQueue).Set(workItemsQueued);
339 GetCounter(STPPerformanceCounterType.WorkItemsProcessed).Set(workItemsProcessed); 339 GetCounter(STPPerformanceCounterType.WorkItemsProcessed).Set(workItemsProcessed);
340 340
341 GetCounter(STPPerformanceCounterType.WorkItemsQueuedPerSecond).Set(workItemsQueued); 341 GetCounter(STPPerformanceCounterType.WorkItemsQueuedPerSecond).Set(workItemsQueued);
342 GetCounter(STPPerformanceCounterType.WorkItemsProcessedPerSecond).Set(workItemsProcessed); 342 GetCounter(STPPerformanceCounterType.WorkItemsProcessedPerSecond).Set(workItemsProcessed);
343 } 343 }
344 344
345 public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime) 345 public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime)
346 { 346 {
347 GetCounter(STPPerformanceCounterType.AvgWorkItemWaitTime).IncrementBy((long)workItemWaitTime.TotalMilliseconds); 347 GetCounter(STPPerformanceCounterType.AvgWorkItemWaitTime).IncrementBy((long)workItemWaitTime.TotalMilliseconds);
348 GetCounter(STPPerformanceCounterType.AvgWorkItemWaitTimeBase).Increment(); 348 GetCounter(STPPerformanceCounterType.AvgWorkItemWaitTimeBase).Increment();
349 } 349 }
350 350
351 public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime) 351 public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime)
352 { 352 {
353 GetCounter(STPPerformanceCounterType.AvgWorkItemProcessTime).IncrementBy((long)workItemProcessTime.TotalMilliseconds); 353 GetCounter(STPPerformanceCounterType.AvgWorkItemProcessTime).IncrementBy((long)workItemProcessTime.TotalMilliseconds);
354 GetCounter(STPPerformanceCounterType.AvgWorkItemProcessTimeBase).Increment(); 354 GetCounter(STPPerformanceCounterType.AvgWorkItemProcessTimeBase).Increment();
355 } 355 }
356 } 356 }
357#endif 357#endif
358 358
359 internal class NullSTPInstancePerformanceCounters : ISTPInstancePerformanceCounters, ISTPPerformanceCountersReader 359 internal class NullSTPInstancePerformanceCounters : ISTPInstancePerformanceCounters, ISTPPerformanceCountersReader
360 { 360 {
361 private static readonly NullSTPInstancePerformanceCounters _instance = new NullSTPInstancePerformanceCounters(); 361 private static readonly NullSTPInstancePerformanceCounters _instance = new NullSTPInstancePerformanceCounters();
362 362
363 public static NullSTPInstancePerformanceCounters Instance 363 public static NullSTPInstancePerformanceCounters Instance
364 { 364 {
365 get { return _instance; } 365 get { return _instance; }
366 } 366 }
367 367
368 public void Close() {} 368 public void Close() {}
369 public void Dispose() {} 369 public void Dispose() {}
370 370
371 public void SampleThreads(long activeThreads, long inUseThreads) {} 371 public void SampleThreads(long activeThreads, long inUseThreads) {}
372 public void SampleWorkItems(long workItemsQueued, long workItemsProcessed) {} 372 public void SampleWorkItems(long workItemsQueued, long workItemsProcessed) {}
373 public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime) {} 373 public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime) {}
374 public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime) {} 374 public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime) {}
375 public long InUseThreads 375 public long InUseThreads
376 { 376 {
377 get { return 0; } 377 get { return 0; }
378 } 378 }
379 379
380 public long ActiveThreads 380 public long ActiveThreads
381 { 381 {
382 get { return 0; } 382 get { return 0; }
383 } 383 }
384 384
385 public long WorkItemsQueued 385 public long WorkItemsQueued
386 { 386 {
387 get { return 0; } 387 get { return 0; }
388 } 388 }
389 389
390 public long WorkItemsProcessed 390 public long WorkItemsProcessed
391 { 391 {
392 get { return 0; } 392 get { return 0; }
393 } 393 }
394 } 394 }
395 395
396 internal class LocalSTPInstancePerformanceCounters : ISTPInstancePerformanceCounters, ISTPPerformanceCountersReader 396 internal class LocalSTPInstancePerformanceCounters : ISTPInstancePerformanceCounters, ISTPPerformanceCountersReader
397 { 397 {
398 public void Close() { } 398 public void Close() { }
399 public void Dispose() { } 399 public void Dispose() { }
400 400
401 private long _activeThreads; 401 private long _activeThreads;
402 private long _inUseThreads; 402 private long _inUseThreads;
403 private long _workItemsQueued; 403 private long _workItemsQueued;
404 private long _workItemsProcessed; 404 private long _workItemsProcessed;
405 405
406 public long InUseThreads 406 public long InUseThreads
407 { 407 {
408 get { return _inUseThreads; } 408 get { return _inUseThreads; }
409 } 409 }
410 410
411 public long ActiveThreads 411 public long ActiveThreads
412 { 412 {
413 get { return _activeThreads; } 413 get { return _activeThreads; }
414 } 414 }
415 415
416 public long WorkItemsQueued 416 public long WorkItemsQueued
417 { 417 {
418 get { return _workItemsQueued; } 418 get { return _workItemsQueued; }
419 } 419 }
420 420
421 public long WorkItemsProcessed 421 public long WorkItemsProcessed
422 { 422 {
423 get { return _workItemsProcessed; } 423 get { return _workItemsProcessed; }
424 } 424 }
425 425
426 public void SampleThreads(long activeThreads, long inUseThreads) 426 public void SampleThreads(long activeThreads, long inUseThreads)
427 { 427 {
428 _activeThreads = activeThreads; 428 _activeThreads = activeThreads;
429 _inUseThreads = inUseThreads; 429 _inUseThreads = inUseThreads;
430 } 430 }
431 431
432 public void SampleWorkItems(long workItemsQueued, long workItemsProcessed) 432 public void SampleWorkItems(long workItemsQueued, long workItemsProcessed)
433 { 433 {
434 _workItemsQueued = workItemsQueued; 434 _workItemsQueued = workItemsQueued;
435 _workItemsProcessed = workItemsProcessed; 435 _workItemsProcessed = workItemsProcessed;
436 } 436 }
437 437
438 public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime) 438 public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime)
439 { 439 {
440 // Not supported 440 // Not supported
441 } 441 }
442 442
443 public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime) 443 public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime)
444 { 444 {
445 // Not supported 445 // Not supported
446 } 446 }
447 } 447 }
448} 448}
diff --git a/ThirdParty/SmartThreadPool/STPStartInfo.cs b/ThirdParty/SmartThreadPool/STPStartInfo.cs
index 2ec8dc6..96fa094 100644
--- a/ThirdParty/SmartThreadPool/STPStartInfo.cs
+++ b/ThirdParty/SmartThreadPool/STPStartInfo.cs
@@ -1,212 +1,212 @@
1using System; 1using System;
2using System.Threading; 2using System.Threading;
3 3
4namespace Amib.Threading 4namespace Amib.Threading
5{ 5{
6 /// <summary> 6 /// <summary>
7 /// Summary description for STPStartInfo. 7 /// Summary description for STPStartInfo.
8 /// </summary> 8 /// </summary>
9 public class STPStartInfo : WIGStartInfo 9 public class STPStartInfo : WIGStartInfo
10 { 10 {
11 private int _idleTimeout = SmartThreadPool.DefaultIdleTimeout; 11 private int _idleTimeout = SmartThreadPool.DefaultIdleTimeout;
12 private int _minWorkerThreads = SmartThreadPool.DefaultMinWorkerThreads; 12 private int _minWorkerThreads = SmartThreadPool.DefaultMinWorkerThreads;
13 private int _maxWorkerThreads = SmartThreadPool.DefaultMaxWorkerThreads; 13 private int _maxWorkerThreads = SmartThreadPool.DefaultMaxWorkerThreads;
14#if !(WINDOWS_PHONE) 14#if !(WINDOWS_PHONE)
15 private ThreadPriority _threadPriority = SmartThreadPool.DefaultThreadPriority; 15 private ThreadPriority _threadPriority = SmartThreadPool.DefaultThreadPriority;
16#endif 16#endif
17 private string _performanceCounterInstanceName = SmartThreadPool.DefaultPerformanceCounterInstanceName; 17 private string _performanceCounterInstanceName = SmartThreadPool.DefaultPerformanceCounterInstanceName;
18 private bool _areThreadsBackground = SmartThreadPool.DefaultAreThreadsBackground; 18 private bool _areThreadsBackground = SmartThreadPool.DefaultAreThreadsBackground;
19 private bool _enableLocalPerformanceCounters; 19 private bool _enableLocalPerformanceCounters;
20 private string _threadPoolName = SmartThreadPool.DefaultThreadPoolName; 20 private string _threadPoolName = SmartThreadPool.DefaultThreadPoolName;
21 private int? _maxStackSize = SmartThreadPool.DefaultMaxStackSize; 21 private int? _maxStackSize = SmartThreadPool.DefaultMaxStackSize;
22 22
23 public STPStartInfo() 23 public STPStartInfo()
24 { 24 {
25 _performanceCounterInstanceName = SmartThreadPool.DefaultPerformanceCounterInstanceName; 25 _performanceCounterInstanceName = SmartThreadPool.DefaultPerformanceCounterInstanceName;
26#if !(WINDOWS_PHONE) 26#if !(WINDOWS_PHONE)
27 _threadPriority = SmartThreadPool.DefaultThreadPriority; 27 _threadPriority = SmartThreadPool.DefaultThreadPriority;
28#endif 28#endif
29 _maxWorkerThreads = SmartThreadPool.DefaultMaxWorkerThreads; 29 _maxWorkerThreads = SmartThreadPool.DefaultMaxWorkerThreads;
30 _idleTimeout = SmartThreadPool.DefaultIdleTimeout; 30 _idleTimeout = SmartThreadPool.DefaultIdleTimeout;
31 _minWorkerThreads = SmartThreadPool.DefaultMinWorkerThreads; 31 _minWorkerThreads = SmartThreadPool.DefaultMinWorkerThreads;
32 } 32 }
33 33
34 public STPStartInfo(STPStartInfo stpStartInfo) 34 public STPStartInfo(STPStartInfo stpStartInfo)
35 : base(stpStartInfo) 35 : base(stpStartInfo)
36 { 36 {
37 _idleTimeout = stpStartInfo.IdleTimeout; 37 _idleTimeout = stpStartInfo.IdleTimeout;
38 _minWorkerThreads = stpStartInfo.MinWorkerThreads; 38 _minWorkerThreads = stpStartInfo.MinWorkerThreads;
39 _maxWorkerThreads = stpStartInfo.MaxWorkerThreads; 39 _maxWorkerThreads = stpStartInfo.MaxWorkerThreads;
40#if !(WINDOWS_PHONE) 40#if !(WINDOWS_PHONE)
41 _threadPriority = stpStartInfo.ThreadPriority; 41 _threadPriority = stpStartInfo.ThreadPriority;
42#endif 42#endif
43 _performanceCounterInstanceName = stpStartInfo.PerformanceCounterInstanceName; 43 _performanceCounterInstanceName = stpStartInfo.PerformanceCounterInstanceName;
44 _enableLocalPerformanceCounters = stpStartInfo._enableLocalPerformanceCounters; 44 _enableLocalPerformanceCounters = stpStartInfo._enableLocalPerformanceCounters;
45 _threadPoolName = stpStartInfo._threadPoolName; 45 _threadPoolName = stpStartInfo._threadPoolName;
46 _areThreadsBackground = stpStartInfo.AreThreadsBackground; 46 _areThreadsBackground = stpStartInfo.AreThreadsBackground;
47#if !(_SILVERLIGHT) && !(WINDOWS_PHONE) 47#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
48 _apartmentState = stpStartInfo._apartmentState; 48 _apartmentState = stpStartInfo._apartmentState;
49#endif 49#endif
50 } 50 }
51 51
52 /// <summary> 52 /// <summary>
53 /// Get/Set the idle timeout in milliseconds. 53 /// Get/Set the idle timeout in milliseconds.
54 /// If a thread is idle (starved) longer than IdleTimeout then it may quit. 54 /// If a thread is idle (starved) longer than IdleTimeout then it may quit.
55 /// </summary> 55 /// </summary>
56 public virtual int IdleTimeout 56 public virtual int IdleTimeout
57 { 57 {
58 get { return _idleTimeout; } 58 get { return _idleTimeout; }
59 set 59 set
60 { 60 {
61 ThrowIfReadOnly(); 61 ThrowIfReadOnly();
62 _idleTimeout = value; 62 _idleTimeout = value;
63 } 63 }
64 } 64 }
65 65
66 66
67 /// <summary> 67 /// <summary>
68 /// Get/Set the lower limit of threads in the pool. 68 /// Get/Set the lower limit of threads in the pool.
69 /// </summary> 69 /// </summary>
70 public virtual int MinWorkerThreads 70 public virtual int MinWorkerThreads
71 { 71 {
72 get { return _minWorkerThreads; } 72 get { return _minWorkerThreads; }
73 set 73 set
74 { 74 {
75 ThrowIfReadOnly(); 75 ThrowIfReadOnly();
76 _minWorkerThreads = value; 76 _minWorkerThreads = value;
77 } 77 }
78 } 78 }
79 79
80 80
81 /// <summary> 81 /// <summary>
82 /// Get/Set the upper limit of threads in the pool. 82 /// Get/Set the upper limit of threads in the pool.
83 /// </summary> 83 /// </summary>
84 public virtual int MaxWorkerThreads 84 public virtual int MaxWorkerThreads
85 { 85 {
86 get { return _maxWorkerThreads; } 86 get { return _maxWorkerThreads; }
87 set 87 set
88 { 88 {
89 ThrowIfReadOnly(); 89 ThrowIfReadOnly();
90 _maxWorkerThreads = value; 90 _maxWorkerThreads = value;
91 } 91 }
92 } 92 }
93 93
94#if !(WINDOWS_PHONE) 94#if !(WINDOWS_PHONE)
95 /// <summary> 95 /// <summary>
96 /// Get/Set the scheduling priority of the threads in the pool. 96 /// Get/Set the scheduling priority of the threads in the pool.
97 /// The Os handles the scheduling. 97 /// The Os handles the scheduling.
98 /// </summary> 98 /// </summary>
99 public virtual ThreadPriority ThreadPriority 99 public virtual ThreadPriority ThreadPriority
100 { 100 {
101 get { return _threadPriority; } 101 get { return _threadPriority; }
102 set 102 set
103 { 103 {
104 ThrowIfReadOnly(); 104 ThrowIfReadOnly();
105 _threadPriority = value; 105 _threadPriority = value;
106 } 106 }
107 } 107 }
108#endif 108#endif
109 /// <summary> 109 /// <summary>
110 /// Get/Set the thread pool name. Threads will get names depending on this. 110 /// Get/Set the thread pool name. Threads will get names depending on this.
111 /// </summary> 111 /// </summary>
112 public virtual string ThreadPoolName { 112 public virtual string ThreadPoolName {
113 get { return _threadPoolName; } 113 get { return _threadPoolName; }
114 set 114 set
115 { 115 {
116 ThrowIfReadOnly (); 116 ThrowIfReadOnly ();
117 _threadPoolName = value; 117 _threadPoolName = value;
118 } 118 }
119 } 119 }
120 120
121 /// <summary> 121 /// <summary>
122 /// Get/Set the performance counter instance name of this SmartThreadPool 122 /// Get/Set the performance counter instance name of this SmartThreadPool
123 /// The default is null which indicate not to use performance counters at all. 123 /// The default is null which indicate not to use performance counters at all.
124 /// </summary> 124 /// </summary>
125 public virtual string PerformanceCounterInstanceName 125 public virtual string PerformanceCounterInstanceName
126 { 126 {
127 get { return _performanceCounterInstanceName; } 127 get { return _performanceCounterInstanceName; }
128 set 128 set
129 { 129 {
130 ThrowIfReadOnly(); 130 ThrowIfReadOnly();
131 _performanceCounterInstanceName = value; 131 _performanceCounterInstanceName = value;
132 } 132 }
133 } 133 }
134 134
135 /// <summary> 135 /// <summary>
136 /// Enable/Disable the local performance counter. 136 /// Enable/Disable the local performance counter.
137 /// This enables the user to get some performance information about the SmartThreadPool 137 /// This enables the user to get some performance information about the SmartThreadPool
138 /// without using Windows performance counters. (Useful on WindowsCE, Silverlight, etc.) 138 /// without using Windows performance counters. (Useful on WindowsCE, Silverlight, etc.)
139 /// The default is false. 139 /// The default is false.
140 /// </summary> 140 /// </summary>
141 public virtual bool EnableLocalPerformanceCounters 141 public virtual bool EnableLocalPerformanceCounters
142 { 142 {
143 get { return _enableLocalPerformanceCounters; } 143 get { return _enableLocalPerformanceCounters; }
144 set 144 set
145 { 145 {
146 ThrowIfReadOnly(); 146 ThrowIfReadOnly();
147 _enableLocalPerformanceCounters = value; 147 _enableLocalPerformanceCounters = value;
148 } 148 }
149 } 149 }
150 150
151 /// <summary> 151 /// <summary>
152 /// Get/Set backgroundness of thread in thread pool. 152 /// Get/Set backgroundness of thread in thread pool.
153 /// </summary> 153 /// </summary>
154 public virtual bool AreThreadsBackground 154 public virtual bool AreThreadsBackground
155 { 155 {
156 get { return _areThreadsBackground; } 156 get { return _areThreadsBackground; }
157 set 157 set
158 { 158 {
159 ThrowIfReadOnly (); 159 ThrowIfReadOnly ();
160 _areThreadsBackground = value; 160 _areThreadsBackground = value;
161 } 161 }
162 } 162 }
163 163
164 /// <summary> 164 /// <summary>
165 /// Get a readonly version of this STPStartInfo. 165 /// Get a readonly version of this STPStartInfo.
166 /// </summary> 166 /// </summary>
167 /// <returns>Returns a readonly reference to this STPStartInfo</returns> 167 /// <returns>Returns a readonly reference to this STPStartInfo</returns>
168 public new STPStartInfo AsReadOnly() 168 public new STPStartInfo AsReadOnly()
169 { 169 {
170 return new STPStartInfo(this) { _readOnly = true }; 170 return new STPStartInfo(this) { _readOnly = true };
171 } 171 }
172 172
173#if !(_SILVERLIGHT) && !(WINDOWS_PHONE) 173#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
174 174
175 private ApartmentState _apartmentState = SmartThreadPool.DefaultApartmentState; 175 private ApartmentState _apartmentState = SmartThreadPool.DefaultApartmentState;
176 176
177 /// <summary> 177 /// <summary>
178 /// Get/Set the apartment state of threads in the thread pool 178 /// Get/Set the apartment state of threads in the thread pool
179 /// </summary> 179 /// </summary>
180 public ApartmentState ApartmentState 180 public ApartmentState ApartmentState
181 { 181 {
182 get { return _apartmentState; } 182 get { return _apartmentState; }
183 set 183 set
184 { 184 {
185 ThrowIfReadOnly(); 185 ThrowIfReadOnly();
186 _apartmentState = value; 186 _apartmentState = value;
187 } 187 }
188 } 188 }
189 189
190#if !(_SILVERLIGHT) && !(WINDOWS_PHONE) 190#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
191 191
192 /// <summary> 192 /// <summary>
193 /// Get/Set the max stack size of threads in the thread pool 193 /// Get/Set the max stack size of threads in the thread pool
194 /// </summary> 194 /// </summary>
195 public int? MaxStackSize 195 public int? MaxStackSize
196 { 196 {
197 get { return _maxStackSize; } 197 get { return _maxStackSize; }
198 set 198 set
199 { 199 {
200 ThrowIfReadOnly(); 200 ThrowIfReadOnly();
201 if (value.HasValue && value.Value < 0) 201 if (value.HasValue && value.Value < 0)
202 { 202 {
203 throw new ArgumentOutOfRangeException("value", "Value must be greater than 0."); 203 throw new ArgumentOutOfRangeException("value", "Value must be greater than 0.");
204 } 204 }
205 _maxStackSize = value; 205 _maxStackSize = value;
206 } 206 }
207 } 207 }
208#endif 208#endif
209 209
210#endif 210#endif
211 } 211 }
212} 212}
diff --git a/ThirdParty/SmartThreadPool/SmartThreadPool.ThreadEntry.cs b/ThirdParty/SmartThreadPool/SmartThreadPool.ThreadEntry.cs
index ba7d73f..d9502bb 100644
--- a/ThirdParty/SmartThreadPool/SmartThreadPool.ThreadEntry.cs
+++ b/ThirdParty/SmartThreadPool/SmartThreadPool.ThreadEntry.cs
@@ -1,60 +1,60 @@
1 1
2using System; 2using System;
3using Amib.Threading.Internal; 3using Amib.Threading.Internal;
4 4
5namespace Amib.Threading 5namespace Amib.Threading
6{ 6{
7 public partial class SmartThreadPool 7 public partial class SmartThreadPool
8 { 8 {
9 #region ThreadEntry class 9 #region ThreadEntry class
10 10
11 internal class ThreadEntry 11 internal class ThreadEntry
12 { 12 {
13 /// <summary> 13 /// <summary>
14 /// The thread creation time 14 /// The thread creation time
15 /// The value is stored as UTC value. 15 /// The value is stored as UTC value.
16 /// </summary> 16 /// </summary>
17 private readonly DateTime _creationTime; 17 private readonly DateTime _creationTime;
18 18
19 /// <summary> 19 /// <summary>
20 /// The last time this thread has been running 20 /// The last time this thread has been running
21 /// It is updated by IAmAlive() method 21 /// It is updated by IAmAlive() method
22 /// The value is stored as UTC value. 22 /// The value is stored as UTC value.
23 /// </summary> 23 /// </summary>
24 private DateTime _lastAliveTime; 24 private DateTime _lastAliveTime;
25 25
26 /// <summary> 26 /// <summary>
27 /// A reference from each thread in the thread pool to its SmartThreadPool 27 /// A reference from each thread in the thread pool to its SmartThreadPool
28 /// object container. 28 /// object container.
29 /// With this variable a thread can know whatever it belongs to a 29 /// With this variable a thread can know whatever it belongs to a
30 /// SmartThreadPool. 30 /// SmartThreadPool.
31 /// </summary> 31 /// </summary>
32 private readonly SmartThreadPool _associatedSmartThreadPool; 32 private readonly SmartThreadPool _associatedSmartThreadPool;
33 33
34 /// <summary> 34 /// <summary>
35 /// A reference to the current work item a thread from the thread pool 35 /// A reference to the current work item a thread from the thread pool
36 /// is executing. 36 /// is executing.
37 /// </summary> 37 /// </summary>
38 public WorkItem CurrentWorkItem { get; set; } 38 public WorkItem CurrentWorkItem { get; set; }
39 39
40 public ThreadEntry(SmartThreadPool stp) 40 public ThreadEntry(SmartThreadPool stp)
41 { 41 {
42 _associatedSmartThreadPool = stp; 42 _associatedSmartThreadPool = stp;
43 _creationTime = DateTime.UtcNow; 43 _creationTime = DateTime.UtcNow;
44 _lastAliveTime = DateTime.MinValue; 44 _lastAliveTime = DateTime.MinValue;
45 } 45 }
46 46
47 public SmartThreadPool AssociatedSmartThreadPool 47 public SmartThreadPool AssociatedSmartThreadPool
48 { 48 {
49 get { return _associatedSmartThreadPool; } 49 get { return _associatedSmartThreadPool; }
50 } 50 }
51 51
52 public void IAmAlive() 52 public void IAmAlive()
53 { 53 {
54 _lastAliveTime = DateTime.UtcNow; 54 _lastAliveTime = DateTime.UtcNow;
55 } 55 }
56 } 56 }
57 57
58 #endregion 58 #endregion
59 } 59 }
60} \ No newline at end of file 60} \ No newline at end of file
diff --git a/ThirdParty/SmartThreadPool/SmartThreadPool.cs b/ThirdParty/SmartThreadPool/SmartThreadPool.cs
index 9256777..a4f4ce5 100644
--- a/ThirdParty/SmartThreadPool/SmartThreadPool.cs
+++ b/ThirdParty/SmartThreadPool/SmartThreadPool.cs
@@ -1,1732 +1,1732 @@
1#region Release History 1#region Release History
2 2
3// Smart Thread Pool 3// Smart Thread Pool
4// 7 Aug 2004 - Initial release 4// 7 Aug 2004 - Initial release
5// 5//
6// 14 Sep 2004 - Bug fixes 6// 14 Sep 2004 - Bug fixes
7// 7//
8// 15 Oct 2004 - Added new features 8// 15 Oct 2004 - Added new features
9// - Work items return result. 9// - Work items return result.
10// - Support waiting synchronization for multiple work items. 10// - Support waiting synchronization for multiple work items.
11// - Work items can be cancelled. 11// - Work items can be cancelled.
12// - Passage of the caller thread’s context to the thread in the pool. 12// - Passage of the caller thread’s context to the thread in the pool.
13// - Minimal usage of WIN32 handles. 13// - Minimal usage of WIN32 handles.
14// - Minor bug fixes. 14// - Minor bug fixes.
15// 15//
16// 26 Dec 2004 - Changes: 16// 26 Dec 2004 - Changes:
17// - Removed static constructors. 17// - Removed static constructors.
18// - Added finalizers. 18// - Added finalizers.
19// - Changed Exceptions so they are serializable. 19// - Changed Exceptions so they are serializable.
20// - Fixed the bug in one of the SmartThreadPool constructors. 20// - Fixed the bug in one of the SmartThreadPool constructors.
21// - Changed the SmartThreadPool.WaitAll() so it will support any number of waiters. 21// - Changed the SmartThreadPool.WaitAll() so it will support any number of waiters.
22// The SmartThreadPool.WaitAny() is still limited by the .NET Framework. 22// The SmartThreadPool.WaitAny() is still limited by the .NET Framework.
23// - Added PostExecute with options on which cases to call it. 23// - Added PostExecute with options on which cases to call it.
24// - Added option to dispose of the state objects. 24// - Added option to dispose of the state objects.
25// - Added a WaitForIdle() method that waits until the work items queue is empty. 25// - Added a WaitForIdle() method that waits until the work items queue is empty.
26// - Added an STPStartInfo class for the initialization of the thread pool. 26// - Added an STPStartInfo class for the initialization of the thread pool.
27// - Changed exception handling so if a work item throws an exception it 27// - Changed exception handling so if a work item throws an exception it
28// is rethrown at GetResult(), rather then firing an UnhandledException event. 28// is rethrown at GetResult(), rather then firing an UnhandledException event.
29// Note that PostExecute exception are always ignored. 29// Note that PostExecute exception are always ignored.
30// 30//
31// 25 Mar 2005 - Changes: 31// 25 Mar 2005 - Changes:
32// - Fixed lost of work items bug 32// - Fixed lost of work items bug
33// 33//
34// 3 Jul 2005: Changes. 34// 3 Jul 2005: Changes.
35// - Fixed bug where Enqueue() throws an exception because PopWaiter() returned null, hardly reconstructed. 35// - Fixed bug where Enqueue() throws an exception because PopWaiter() returned null, hardly reconstructed.
36// 36//
37// 16 Aug 2005: Changes. 37// 16 Aug 2005: Changes.
38// - Fixed bug where the InUseThreads becomes negative when canceling work items. 38// - Fixed bug where the InUseThreads becomes negative when canceling work items.
39// 39//
40// 31 Jan 2006 - Changes: 40// 31 Jan 2006 - Changes:
41// - Added work items priority 41// - Added work items priority
42// - Removed support of chained delegates in callbacks and post executes (nobody really use this) 42// - Removed support of chained delegates in callbacks and post executes (nobody really use this)
43// - Added work items groups 43// - Added work items groups
44// - Added work items groups idle event 44// - Added work items groups idle event
45// - Changed SmartThreadPool.WaitAll() behavior so when it gets empty array 45// - Changed SmartThreadPool.WaitAll() behavior so when it gets empty array
46// it returns true rather then throwing an exception. 46// it returns true rather then throwing an exception.
47// - Added option to start the STP and the WIG as suspended 47// - Added option to start the STP and the WIG as suspended
48// - Exception behavior changed, the real exception is returned by an 48// - Exception behavior changed, the real exception is returned by an
49// inner exception 49// inner exception
50// - Added option to keep the Http context of the caller thread. (Thanks to Steven T.) 50// - Added option to keep the Http context of the caller thread. (Thanks to Steven T.)
51// - Added performance counters 51// - Added performance counters
52// - Added priority to the threads in the pool 52// - Added priority to the threads in the pool
53// 53//
54// 13 Feb 2006 - Changes: 54// 13 Feb 2006 - Changes:
55// - Added a call to the dispose of the Performance Counter so 55// - Added a call to the dispose of the Performance Counter so
56// their won't be a Performance Counter leak. 56// their won't be a Performance Counter leak.
57// - Added exception catch in case the Performance Counters cannot 57// - Added exception catch in case the Performance Counters cannot
58// be created. 58// be created.
59// 59//
60// 17 May 2008 - Changes: 60// 17 May 2008 - Changes:
61// - Changed the dispose behavior and removed the Finalizers. 61// - Changed the dispose behavior and removed the Finalizers.
62// - Enabled the change of the MaxThreads and MinThreads at run time. 62// - Enabled the change of the MaxThreads and MinThreads at run time.
63// - Enabled the change of the Concurrency of a IWorkItemsGroup at run 63// - Enabled the change of the Concurrency of a IWorkItemsGroup at run
64// time If the IWorkItemsGroup is a SmartThreadPool then the Concurrency 64// time If the IWorkItemsGroup is a SmartThreadPool then the Concurrency
65// refers to the MaxThreads. 65// refers to the MaxThreads.
66// - Improved the cancel behavior. 66// - Improved the cancel behavior.
67// - Added events for thread creation and termination. 67// - Added events for thread creation and termination.
68// - Fixed the HttpContext context capture. 68// - Fixed the HttpContext context capture.
69// - Changed internal collections so they use generic collections 69// - Changed internal collections so they use generic collections
70// - Added IsIdle flag to the SmartThreadPool and IWorkItemsGroup 70// - Added IsIdle flag to the SmartThreadPool and IWorkItemsGroup
71// - Added support for WinCE 71// - Added support for WinCE
72// - Added support for Action<T> and Func<T> 72// - Added support for Action<T> and Func<T>
73// 73//
74// 07 April 2009 - Changes: 74// 07 April 2009 - Changes:
75// - Added support for Silverlight and Mono 75// - Added support for Silverlight and Mono
76// - Added Join, Choice, and Pipe to SmartThreadPool. 76// - Added Join, Choice, and Pipe to SmartThreadPool.
77// - Added local performance counters (for Mono, Silverlight, and WindowsCE) 77// - Added local performance counters (for Mono, Silverlight, and WindowsCE)
78// - Changed duration measures from DateTime.Now to Stopwatch. 78// - Changed duration measures from DateTime.Now to Stopwatch.
79// - Queues changed from System.Collections.Queue to System.Collections.Generic.LinkedList<T>. 79// - Queues changed from System.Collections.Queue to System.Collections.Generic.LinkedList<T>.
80// 80//
81// 21 December 2009 - Changes: 81// 21 December 2009 - Changes:
82// - Added work item timeout (passive) 82// - Added work item timeout (passive)
83// 83//
84// 20 August 2012 - Changes: 84// 20 August 2012 - Changes:
85// - Added set name to threads 85// - Added set name to threads
86// - Fixed the WorkItemsQueue.Dequeue. 86// - Fixed the WorkItemsQueue.Dequeue.
87// Replaced while (!Monitor.TryEnter(this)); with lock(this) { ... } 87// Replaced while (!Monitor.TryEnter(this)); with lock(this) { ... }
88// - Fixed SmartThreadPool.Pipe 88// - Fixed SmartThreadPool.Pipe
89// - Added IsBackground option to threads 89// - Added IsBackground option to threads
90// - Added ApartmentState to threads 90// - Added ApartmentState to threads
91// - Fixed thread creation when queuing many work items at the same time. 91// - Fixed thread creation when queuing many work items at the same time.
92// 92//
93// 24 August 2012 - Changes: 93// 24 August 2012 - Changes:
94// - Enabled cancel abort after cancel. See: http://smartthreadpool.codeplex.com/discussions/345937 by alecswan 94// - Enabled cancel abort after cancel. See: http://smartthreadpool.codeplex.com/discussions/345937 by alecswan
95// - Added option to set MaxStackSize of threads 95// - Added option to set MaxStackSize of threads
96 96
97#endregion 97#endregion
98 98
99using System; 99using System;
100using System.Security; 100using System.Security;
101using System.Threading; 101using System.Threading;
102using System.Collections; 102using System.Collections;
103using System.Collections.Generic; 103using System.Collections.Generic;
104using System.Diagnostics; 104using System.Diagnostics;
105using System.Runtime.CompilerServices; 105using System.Runtime.CompilerServices;
106 106
107using Amib.Threading.Internal; 107using Amib.Threading.Internal;
108 108
109namespace Amib.Threading 109namespace Amib.Threading
110{ 110{
111 #region SmartThreadPool class 111 #region SmartThreadPool class
112 /// <summary> 112 /// <summary>
113 /// Smart thread pool class. 113 /// Smart thread pool class.
114 /// </summary> 114 /// </summary>
115 public partial class SmartThreadPool : WorkItemsGroupBase, IDisposable 115 public partial class SmartThreadPool : WorkItemsGroupBase, IDisposable
116 { 116 {
117 #region Public Default Constants 117 #region Public Default Constants
118 118
119 /// <summary> 119 /// <summary>
120 /// Default minimum number of threads the thread pool contains. (0) 120 /// Default minimum number of threads the thread pool contains. (0)
121 /// </summary> 121 /// </summary>
122 public const int DefaultMinWorkerThreads = 0; 122 public const int DefaultMinWorkerThreads = 0;
123 123
124 /// <summary> 124 /// <summary>
125 /// Default maximum number of threads the thread pool contains. (25) 125 /// Default maximum number of threads the thread pool contains. (25)
126 /// </summary> 126 /// </summary>
127 public const int DefaultMaxWorkerThreads = 25; 127 public const int DefaultMaxWorkerThreads = 25;
128 128
129 /// <summary> 129 /// <summary>
130 /// Default idle timeout in milliseconds. (One minute) 130 /// Default idle timeout in milliseconds. (One minute)
131 /// </summary> 131 /// </summary>
132 public const int DefaultIdleTimeout = 60*1000; // One minute 132 public const int DefaultIdleTimeout = 60*1000; // One minute
133 133
134 /// <summary> 134 /// <summary>
135 /// Indicate to copy the security context of the caller and then use it in the call. (false) 135 /// Indicate to copy the security context of the caller and then use it in the call. (false)
136 /// </summary> 136 /// </summary>
137 public const bool DefaultUseCallerCallContext = false; 137 public const bool DefaultUseCallerCallContext = false;
138 138
139 /// <summary> 139 /// <summary>
140 /// Indicate to copy the HTTP context of the caller and then use it in the call. (false) 140 /// Indicate to copy the HTTP context of the caller and then use it in the call. (false)
141 /// </summary> 141 /// </summary>
142 public const bool DefaultUseCallerHttpContext = false; 142 public const bool DefaultUseCallerHttpContext = false;
143 143
144 /// <summary> 144 /// <summary>
145 /// Indicate to dispose of the state objects if they support the IDispose interface. (false) 145 /// Indicate to dispose of the state objects if they support the IDispose interface. (false)
146 /// </summary> 146 /// </summary>
147 public const bool DefaultDisposeOfStateObjects = false; 147 public const bool DefaultDisposeOfStateObjects = false;
148 148
149 /// <summary> 149 /// <summary>
150 /// The default option to run the post execute (CallToPostExecute.Always) 150 /// The default option to run the post execute (CallToPostExecute.Always)
151 /// </summary> 151 /// </summary>
152 public const CallToPostExecute DefaultCallToPostExecute = CallToPostExecute.Always; 152 public const CallToPostExecute DefaultCallToPostExecute = CallToPostExecute.Always;
153 153
154 /// <summary> 154 /// <summary>
155 /// The default post execute method to run. (None) 155 /// The default post execute method to run. (None)
156 /// When null it means not to call it. 156 /// When null it means not to call it.
157 /// </summary> 157 /// </summary>
158 public static readonly PostExecuteWorkItemCallback DefaultPostExecuteWorkItemCallback; 158 public static readonly PostExecuteWorkItemCallback DefaultPostExecuteWorkItemCallback;
159 159
160 /// <summary> 160 /// <summary>
161 /// The default work item priority (WorkItemPriority.Normal) 161 /// The default work item priority (WorkItemPriority.Normal)
162 /// </summary> 162 /// </summary>
163 public const WorkItemPriority DefaultWorkItemPriority = WorkItemPriority.Normal; 163 public const WorkItemPriority DefaultWorkItemPriority = WorkItemPriority.Normal;
164 164
165 /// <summary> 165 /// <summary>
166 /// The default is to work on work items as soon as they arrive 166 /// The default is to work on work items as soon as they arrive
167 /// and not to wait for the start. (false) 167 /// and not to wait for the start. (false)
168 /// </summary> 168 /// </summary>
169 public const bool DefaultStartSuspended = false; 169 public const bool DefaultStartSuspended = false;
170 170
171 /// <summary> 171 /// <summary>
172 /// The default name to use for the performance counters instance. (null) 172 /// The default name to use for the performance counters instance. (null)
173 /// </summary> 173 /// </summary>
174 public static readonly string DefaultPerformanceCounterInstanceName; 174 public static readonly string DefaultPerformanceCounterInstanceName;
175 175
176#if !(WINDOWS_PHONE) 176#if !(WINDOWS_PHONE)
177 177
178 /// <summary> 178 /// <summary>
179 /// The default thread priority (ThreadPriority.Normal) 179 /// The default thread priority (ThreadPriority.Normal)
180 /// </summary> 180 /// </summary>
181 public const ThreadPriority DefaultThreadPriority = ThreadPriority.Normal; 181 public const ThreadPriority DefaultThreadPriority = ThreadPriority.Normal;
182#endif 182#endif
183 /// <summary> 183 /// <summary>
184 /// The default thread pool name. (SmartThreadPool) 184 /// The default thread pool name. (SmartThreadPool)
185 /// </summary> 185 /// </summary>
186 public const string DefaultThreadPoolName = "SmartThreadPool"; 186 public const string DefaultThreadPoolName = "SmartThreadPool";
187 187
188 /// <summary> 188 /// <summary>
189 /// The default Max Stack Size. (SmartThreadPool) 189 /// The default Max Stack Size. (SmartThreadPool)
190 /// </summary> 190 /// </summary>
191 public static readonly int? DefaultMaxStackSize = null; 191 public static readonly int? DefaultMaxStackSize = null;
192 192
193 /// <summary> 193 /// <summary>
194 /// The default fill state with params. (false) 194 /// The default fill state with params. (false)
195 /// It is relevant only to QueueWorkItem of Action&lt;...&gt;/Func&lt;...&gt; 195 /// It is relevant only to QueueWorkItem of Action&lt;...&gt;/Func&lt;...&gt;
196 /// </summary> 196 /// </summary>
197 public const bool DefaultFillStateWithArgs = false; 197 public const bool DefaultFillStateWithArgs = false;
198 198
199 /// <summary> 199 /// <summary>
200 /// The default thread backgroundness. (true) 200 /// The default thread backgroundness. (true)
201 /// </summary> 201 /// </summary>
202 public const bool DefaultAreThreadsBackground = true; 202 public const bool DefaultAreThreadsBackground = true;
203 203
204#if !(_SILVERLIGHT) && !(WINDOWS_PHONE) 204#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
205 /// <summary> 205 /// <summary>
206 /// The default apartment state of a thread in the thread pool. 206 /// The default apartment state of a thread in the thread pool.
207 /// The default is ApartmentState.Unknown which means the STP will not 207 /// The default is ApartmentState.Unknown which means the STP will not
208 /// set the apartment of the thread. It will use the .NET default. 208 /// set the apartment of the thread. It will use the .NET default.
209 /// </summary> 209 /// </summary>
210 public const ApartmentState DefaultApartmentState = ApartmentState.Unknown; 210 public const ApartmentState DefaultApartmentState = ApartmentState.Unknown;
211#endif 211#endif
212 212
213 #endregion 213 #endregion
214 214
215 #region Member Variables 215 #region Member Variables
216 216
217 /// <summary> 217 /// <summary>
218 /// Dictionary of all the threads in the thread pool. 218 /// Dictionary of all the threads in the thread pool.
219 /// </summary> 219 /// </summary>
220 private readonly SynchronizedDictionary<Thread, ThreadEntry> _workerThreads = new SynchronizedDictionary<Thread, ThreadEntry>(); 220 private readonly SynchronizedDictionary<Thread, ThreadEntry> _workerThreads = new SynchronizedDictionary<Thread, ThreadEntry>();
221 221
222 /// <summary> 222 /// <summary>
223 /// Queue of work items. 223 /// Queue of work items.
224 /// </summary> 224 /// </summary>
225 private readonly WorkItemsQueue _workItemsQueue = new WorkItemsQueue(); 225 private readonly WorkItemsQueue _workItemsQueue = new WorkItemsQueue();
226 226
227 /// <summary> 227 /// <summary>
228 /// Count the work items handled. 228 /// Count the work items handled.
229 /// Used by the performance counter. 229 /// Used by the performance counter.
230 /// </summary> 230 /// </summary>
231 private int _workItemsProcessed; 231 private int _workItemsProcessed;
232 232
233 /// <summary> 233 /// <summary>
234 /// Number of threads that currently work (not idle). 234 /// Number of threads that currently work (not idle).
235 /// </summary> 235 /// </summary>
236 private int _inUseWorkerThreads; 236 private int _inUseWorkerThreads;
237 237
238 /// <summary> 238 /// <summary>
239 /// Stores a copy of the original STPStartInfo. 239 /// Stores a copy of the original STPStartInfo.
240 /// It is used to change the MinThread and MaxThreads 240 /// It is used to change the MinThread and MaxThreads
241 /// </summary> 241 /// </summary>
242 private STPStartInfo _stpStartInfo; 242 private STPStartInfo _stpStartInfo;
243 243
244 /// <summary> 244 /// <summary>
245 /// Total number of work items that are stored in the work items queue 245 /// Total number of work items that are stored in the work items queue
246 /// plus the work items that the threads in the pool are working on. 246 /// plus the work items that the threads in the pool are working on.
247 /// </summary> 247 /// </summary>
248 private int _currentWorkItemsCount; 248 private int _currentWorkItemsCount;
249 249
250 /// <summary> 250 /// <summary>
251 /// Signaled when the thread pool is idle, i.e. no thread is busy 251 /// Signaled when the thread pool is idle, i.e. no thread is busy
252 /// and the work items queue is empty 252 /// and the work items queue is empty
253 /// </summary> 253 /// </summary>
254 //private ManualResetEvent _isIdleWaitHandle = new ManualResetEvent(true); 254 //private ManualResetEvent _isIdleWaitHandle = new ManualResetEvent(true);
255 private ManualResetEvent _isIdleWaitHandle = EventWaitHandleFactory.CreateManualResetEvent(true); 255 private ManualResetEvent _isIdleWaitHandle = EventWaitHandleFactory.CreateManualResetEvent(true);
256 256
257 /// <summary> 257 /// <summary>
258 /// An event to signal all the threads to quit immediately. 258 /// An event to signal all the threads to quit immediately.
259 /// </summary> 259 /// </summary>
260 //private ManualResetEvent _shuttingDownEvent = new ManualResetEvent(false); 260 //private ManualResetEvent _shuttingDownEvent = new ManualResetEvent(false);
261 private ManualResetEvent _shuttingDownEvent = EventWaitHandleFactory.CreateManualResetEvent(false); 261 private ManualResetEvent _shuttingDownEvent = EventWaitHandleFactory.CreateManualResetEvent(false);
262 262
263 /// <summary> 263 /// <summary>
264 /// A flag to indicate if the Smart Thread Pool is now suspended. 264 /// A flag to indicate if the Smart Thread Pool is now suspended.
265 /// </summary> 265 /// </summary>
266 private bool _isSuspended; 266 private bool _isSuspended;
267 267
268 /// <summary> 268 /// <summary>
269 /// A flag to indicate the threads to quit. 269 /// A flag to indicate the threads to quit.
270 /// </summary> 270 /// </summary>
271 private bool _shutdown; 271 private bool _shutdown;
272 272
273 /// <summary> 273 /// <summary>
274 /// Counts the threads created in the pool. 274 /// Counts the threads created in the pool.
275 /// It is used to name the threads. 275 /// It is used to name the threads.
276 /// </summary> 276 /// </summary>
277 private int _threadCounter; 277 private int _threadCounter;
278 278
279 /// <summary> 279 /// <summary>
280 /// Indicate that the SmartThreadPool has been disposed 280 /// Indicate that the SmartThreadPool has been disposed
281 /// </summary> 281 /// </summary>
282 private bool _isDisposed; 282 private bool _isDisposed;
283 283
284 /// <summary> 284 /// <summary>
285 /// Holds all the WorkItemsGroup instaces that have at least one 285 /// Holds all the WorkItemsGroup instaces that have at least one
286 /// work item int the SmartThreadPool 286 /// work item int the SmartThreadPool
287 /// This variable is used in case of Shutdown 287 /// This variable is used in case of Shutdown
288 /// </summary> 288 /// </summary>
289 private readonly SynchronizedDictionary<IWorkItemsGroup, IWorkItemsGroup> _workItemsGroups = new SynchronizedDictionary<IWorkItemsGroup, IWorkItemsGroup>(); 289 private readonly SynchronizedDictionary<IWorkItemsGroup, IWorkItemsGroup> _workItemsGroups = new SynchronizedDictionary<IWorkItemsGroup, IWorkItemsGroup>();
290 290
291 /// <summary> 291 /// <summary>
292 /// A common object for all the work items int the STP 292 /// A common object for all the work items int the STP
293 /// so we can mark them to cancel in O(1) 293 /// so we can mark them to cancel in O(1)
294 /// </summary> 294 /// </summary>
295 private CanceledWorkItemsGroup _canceledSmartThreadPool = new CanceledWorkItemsGroup(); 295 private CanceledWorkItemsGroup _canceledSmartThreadPool = new CanceledWorkItemsGroup();
296 296
297 /// <summary> 297 /// <summary>
298 /// Windows STP performance counters 298 /// Windows STP performance counters
299 /// </summary> 299 /// </summary>
300 private ISTPInstancePerformanceCounters _windowsPCs = NullSTPInstancePerformanceCounters.Instance; 300 private ISTPInstancePerformanceCounters _windowsPCs = NullSTPInstancePerformanceCounters.Instance;
301 301
302 /// <summary> 302 /// <summary>
303 /// Local STP performance counters 303 /// Local STP performance counters
304 /// </summary> 304 /// </summary>
305 private ISTPInstancePerformanceCounters _localPCs = NullSTPInstancePerformanceCounters.Instance; 305 private ISTPInstancePerformanceCounters _localPCs = NullSTPInstancePerformanceCounters.Instance;
306 306
307 307
308#if (WINDOWS_PHONE) 308#if (WINDOWS_PHONE)
309 private static readonly Dictionary<int, ThreadEntry> _threadEntries = new Dictionary<int, ThreadEntry>(); 309 private static readonly Dictionary<int, ThreadEntry> _threadEntries = new Dictionary<int, ThreadEntry>();
310#elif (_WINDOWS_CE) 310#elif (_WINDOWS_CE)
311 private static LocalDataStoreSlot _threadEntrySlot = Thread.AllocateDataSlot(); 311 private static LocalDataStoreSlot _threadEntrySlot = Thread.AllocateDataSlot();
312#else 312#else
313 [ThreadStatic] 313 [ThreadStatic]
314 private static ThreadEntry _threadEntry; 314 private static ThreadEntry _threadEntry;
315 315
316#endif 316#endif
317 317
318 /// <summary> 318 /// <summary>
319 /// An event to call after a thread is created, but before 319 /// An event to call after a thread is created, but before
320 /// it's first use. 320 /// it's first use.
321 /// </summary> 321 /// </summary>
322 private event ThreadInitializationHandler _onThreadInitialization; 322 private event ThreadInitializationHandler _onThreadInitialization;
323 323
324 /// <summary> 324 /// <summary>
325 /// An event to call when a thread is about to exit, after 325 /// An event to call when a thread is about to exit, after
326 /// it is no longer belong to the pool. 326 /// it is no longer belong to the pool.
327 /// </summary> 327 /// </summary>
328 private event ThreadTerminationHandler _onThreadTermination; 328 private event ThreadTerminationHandler _onThreadTermination;
329 329
330 #endregion 330 #endregion
331 331
332 #region Per thread properties 332 #region Per thread properties
333 333
334 /// <summary> 334 /// <summary>
335 /// A reference to the current work item a thread from the thread pool 335 /// A reference to the current work item a thread from the thread pool
336 /// is executing. 336 /// is executing.
337 /// </summary> 337 /// </summary>
338 internal static ThreadEntry CurrentThreadEntry 338 internal static ThreadEntry CurrentThreadEntry
339 { 339 {
340#if (WINDOWS_PHONE) 340#if (WINDOWS_PHONE)
341 get 341 get
342 { 342 {
343 lock(_threadEntries) 343 lock(_threadEntries)
344 { 344 {
345 ThreadEntry threadEntry; 345 ThreadEntry threadEntry;
346 if (_threadEntries.TryGetValue(Thread.CurrentThread.ManagedThreadId, out threadEntry)) 346 if (_threadEntries.TryGetValue(Thread.CurrentThread.ManagedThreadId, out threadEntry))
347 { 347 {
348 return threadEntry; 348 return threadEntry;
349 } 349 }
350 } 350 }
351 return null; 351 return null;
352 } 352 }
353 set 353 set
354 { 354 {
355 lock(_threadEntries) 355 lock(_threadEntries)
356 { 356 {
357 _threadEntries[Thread.CurrentThread.ManagedThreadId] = value; 357 _threadEntries[Thread.CurrentThread.ManagedThreadId] = value;
358 } 358 }
359 } 359 }
360#elif (_WINDOWS_CE) 360#elif (_WINDOWS_CE)
361 get 361 get
362 { 362 {
363 //Thread.CurrentThread.ManagedThreadId 363 //Thread.CurrentThread.ManagedThreadId
364 return Thread.GetData(_threadEntrySlot) as ThreadEntry; 364 return Thread.GetData(_threadEntrySlot) as ThreadEntry;
365 } 365 }
366 set 366 set
367 { 367 {
368 Thread.SetData(_threadEntrySlot, value); 368 Thread.SetData(_threadEntrySlot, value);
369 } 369 }
370#else 370#else
371 get 371 get
372 { 372 {
373 return _threadEntry; 373 return _threadEntry;
374 } 374 }
375 set 375 set
376 { 376 {
377 _threadEntry = value; 377 _threadEntry = value;
378 } 378 }
379#endif 379#endif
380 } 380 }
381 #endregion 381 #endregion
382 382
383 #region Construction and Finalization 383 #region Construction and Finalization
384 384
385 /// <summary> 385 /// <summary>
386 /// Constructor 386 /// Constructor
387 /// </summary> 387 /// </summary>
388 public SmartThreadPool() 388 public SmartThreadPool()
389 { 389 {
390 _stpStartInfo = new STPStartInfo(); 390 _stpStartInfo = new STPStartInfo();
391 Initialize(); 391 Initialize();
392 } 392 }
393 393
394 /// <summary> 394 /// <summary>
395 /// Constructor 395 /// Constructor
396 /// </summary> 396 /// </summary>
397 /// <param name="idleTimeout">Idle timeout in milliseconds</param> 397 /// <param name="idleTimeout">Idle timeout in milliseconds</param>
398 public SmartThreadPool(int idleTimeout) 398 public SmartThreadPool(int idleTimeout)
399 { 399 {
400 _stpStartInfo = new STPStartInfo 400 _stpStartInfo = new STPStartInfo
401 { 401 {
402 IdleTimeout = idleTimeout, 402 IdleTimeout = idleTimeout,
403 }; 403 };
404 Initialize(); 404 Initialize();
405 } 405 }
406 406
407 /// <summary> 407 /// <summary>
408 /// Constructor 408 /// Constructor
409 /// </summary> 409 /// </summary>
410 /// <param name="idleTimeout">Idle timeout in milliseconds</param> 410 /// <param name="idleTimeout">Idle timeout in milliseconds</param>
411 /// <param name="maxWorkerThreads">Upper limit of threads in the pool</param> 411 /// <param name="maxWorkerThreads">Upper limit of threads in the pool</param>
412 public SmartThreadPool( 412 public SmartThreadPool(
413 int idleTimeout, 413 int idleTimeout,
414 int maxWorkerThreads) 414 int maxWorkerThreads)
415 { 415 {
416 _stpStartInfo = new STPStartInfo 416 _stpStartInfo = new STPStartInfo
417 { 417 {
418 IdleTimeout = idleTimeout, 418 IdleTimeout = idleTimeout,
419 MaxWorkerThreads = maxWorkerThreads, 419 MaxWorkerThreads = maxWorkerThreads,
420 }; 420 };
421 Initialize(); 421 Initialize();
422 } 422 }
423 423
424 /// <summary> 424 /// <summary>
425 /// Constructor 425 /// Constructor
426 /// </summary> 426 /// </summary>
427 /// <param name="idleTimeout">Idle timeout in milliseconds</param> 427 /// <param name="idleTimeout">Idle timeout in milliseconds</param>
428 /// <param name="maxWorkerThreads">Upper limit of threads in the pool</param> 428 /// <param name="maxWorkerThreads">Upper limit of threads in the pool</param>
429 /// <param name="minWorkerThreads">Lower limit of threads in the pool</param> 429 /// <param name="minWorkerThreads">Lower limit of threads in the pool</param>
430 public SmartThreadPool( 430 public SmartThreadPool(
431 int idleTimeout, 431 int idleTimeout,
432 int maxWorkerThreads, 432 int maxWorkerThreads,
433 int minWorkerThreads) 433 int minWorkerThreads)
434 { 434 {
435 _stpStartInfo = new STPStartInfo 435 _stpStartInfo = new STPStartInfo
436 { 436 {
437 IdleTimeout = idleTimeout, 437 IdleTimeout = idleTimeout,
438 MaxWorkerThreads = maxWorkerThreads, 438 MaxWorkerThreads = maxWorkerThreads,
439 MinWorkerThreads = minWorkerThreads, 439 MinWorkerThreads = minWorkerThreads,
440 }; 440 };
441 Initialize(); 441 Initialize();
442 } 442 }
443 443
444 /// <summary> 444 /// <summary>
445 /// Constructor 445 /// Constructor
446 /// </summary> 446 /// </summary>
447 /// <param name="stpStartInfo">A SmartThreadPool configuration that overrides the default behavior</param> 447 /// <param name="stpStartInfo">A SmartThreadPool configuration that overrides the default behavior</param>
448 public SmartThreadPool(STPStartInfo stpStartInfo) 448 public SmartThreadPool(STPStartInfo stpStartInfo)
449 { 449 {
450 _stpStartInfo = new STPStartInfo(stpStartInfo); 450 _stpStartInfo = new STPStartInfo(stpStartInfo);
451 Initialize(); 451 Initialize();
452 } 452 }
453 453
454 private void Initialize() 454 private void Initialize()
455 { 455 {
456 Name = _stpStartInfo.ThreadPoolName; 456 Name = _stpStartInfo.ThreadPoolName;
457 ValidateSTPStartInfo(); 457 ValidateSTPStartInfo();
458 458
459 // _stpStartInfoRW stores a read/write copy of the STPStartInfo. 459 // _stpStartInfoRW stores a read/write copy of the STPStartInfo.
460 // Actually only MaxWorkerThreads and MinWorkerThreads are overwritten 460 // Actually only MaxWorkerThreads and MinWorkerThreads are overwritten
461 461
462 _isSuspended = _stpStartInfo.StartSuspended; 462 _isSuspended = _stpStartInfo.StartSuspended;
463 463
464#if (_WINDOWS_CE) || (_SILVERLIGHT) || (_MONO) || (WINDOWS_PHONE) 464#if (_WINDOWS_CE) || (_SILVERLIGHT) || (_MONO) || (WINDOWS_PHONE)
465 if (null != _stpStartInfo.PerformanceCounterInstanceName) 465 if (null != _stpStartInfo.PerformanceCounterInstanceName)
466 { 466 {
467 throw new NotSupportedException("Performance counters are not implemented for Compact Framework/Silverlight/Mono, instead use StpStartInfo.EnableLocalPerformanceCounters"); 467 throw new NotSupportedException("Performance counters are not implemented for Compact Framework/Silverlight/Mono, instead use StpStartInfo.EnableLocalPerformanceCounters");
468 } 468 }
469#else 469#else
470 if (null != _stpStartInfo.PerformanceCounterInstanceName) 470 if (null != _stpStartInfo.PerformanceCounterInstanceName)
471 { 471 {
472 try 472 try
473 { 473 {
474 _windowsPCs = new STPInstancePerformanceCounters(_stpStartInfo.PerformanceCounterInstanceName); 474 _windowsPCs = new STPInstancePerformanceCounters(_stpStartInfo.PerformanceCounterInstanceName);
475 } 475 }
476 catch (Exception e) 476 catch (Exception e)
477 { 477 {
478 Debug.WriteLine("Unable to create Performance Counters: " + e); 478 Debug.WriteLine("Unable to create Performance Counters: " + e);
479 _windowsPCs = NullSTPInstancePerformanceCounters.Instance; 479 _windowsPCs = NullSTPInstancePerformanceCounters.Instance;
480 } 480 }
481 } 481 }
482#endif 482#endif
483 483
484 if (_stpStartInfo.EnableLocalPerformanceCounters) 484 if (_stpStartInfo.EnableLocalPerformanceCounters)
485 { 485 {
486 _localPCs = new LocalSTPInstancePerformanceCounters(); 486 _localPCs = new LocalSTPInstancePerformanceCounters();
487 } 487 }
488 488
489 // If the STP is not started suspended then start the threads. 489 // If the STP is not started suspended then start the threads.
490 if (!_isSuspended) 490 if (!_isSuspended)
491 { 491 {
492 StartOptimalNumberOfThreads(); 492 StartOptimalNumberOfThreads();
493 } 493 }
494 } 494 }
495 495
496 private void StartOptimalNumberOfThreads() 496 private void StartOptimalNumberOfThreads()
497 { 497 {
498 int threadsCount = Math.Max(_workItemsQueue.Count, _stpStartInfo.MinWorkerThreads); 498 int threadsCount = Math.Max(_workItemsQueue.Count, _stpStartInfo.MinWorkerThreads);
499 threadsCount = Math.Min(threadsCount, _stpStartInfo.MaxWorkerThreads); 499 threadsCount = Math.Min(threadsCount, _stpStartInfo.MaxWorkerThreads);
500 threadsCount -= _workerThreads.Count; 500 threadsCount -= _workerThreads.Count;
501 if (threadsCount > 0) 501 if (threadsCount > 0)
502 { 502 {
503 StartThreads(threadsCount); 503 StartThreads(threadsCount);
504 } 504 }
505 } 505 }
506 506
507 private void ValidateSTPStartInfo() 507 private void ValidateSTPStartInfo()
508 { 508 {
509 if (_stpStartInfo.MinWorkerThreads < 0) 509 if (_stpStartInfo.MinWorkerThreads < 0)
510 { 510 {
511 throw new ArgumentOutOfRangeException( 511 throw new ArgumentOutOfRangeException(
512 "MinWorkerThreads", "MinWorkerThreads cannot be negative"); 512 "MinWorkerThreads", "MinWorkerThreads cannot be negative");
513 } 513 }
514 514
515 if (_stpStartInfo.MaxWorkerThreads <= 0) 515 if (_stpStartInfo.MaxWorkerThreads <= 0)
516 { 516 {
517 throw new ArgumentOutOfRangeException( 517 throw new ArgumentOutOfRangeException(
518 "MaxWorkerThreads", "MaxWorkerThreads must be greater than zero"); 518 "MaxWorkerThreads", "MaxWorkerThreads must be greater than zero");
519 } 519 }
520 520
521 if (_stpStartInfo.MinWorkerThreads > _stpStartInfo.MaxWorkerThreads) 521 if (_stpStartInfo.MinWorkerThreads > _stpStartInfo.MaxWorkerThreads)
522 { 522 {
523 throw new ArgumentOutOfRangeException( 523 throw new ArgumentOutOfRangeException(
524 "MinWorkerThreads, maxWorkerThreads", 524 "MinWorkerThreads, maxWorkerThreads",
525 "MaxWorkerThreads must be greater or equal to MinWorkerThreads"); 525 "MaxWorkerThreads must be greater or equal to MinWorkerThreads");
526 } 526 }
527 } 527 }
528 528
529 private static void ValidateCallback(Delegate callback) 529 private static void ValidateCallback(Delegate callback)
530 { 530 {
531 if(callback.GetInvocationList().Length > 1) 531 if(callback.GetInvocationList().Length > 1)
532 { 532 {
533 throw new NotSupportedException("SmartThreadPool doesn't support delegates chains"); 533 throw new NotSupportedException("SmartThreadPool doesn't support delegates chains");
534 } 534 }
535 } 535 }
536 536
537 #endregion 537 #endregion
538 538
539 #region Thread Processing 539 #region Thread Processing
540 540
541 /// <summary> 541 /// <summary>
542 /// Waits on the queue for a work item, shutdown, or timeout. 542 /// Waits on the queue for a work item, shutdown, or timeout.
543 /// </summary> 543 /// </summary>
544 /// <returns> 544 /// <returns>
545 /// Returns the WaitingCallback or null in case of timeout or shutdown. 545 /// Returns the WaitingCallback or null in case of timeout or shutdown.
546 /// </returns> 546 /// </returns>
547 private WorkItem Dequeue() 547 private WorkItem Dequeue()
548 { 548 {
549 WorkItem workItem = 549 WorkItem workItem =
550 _workItemsQueue.DequeueWorkItem(_stpStartInfo.IdleTimeout, _shuttingDownEvent); 550 _workItemsQueue.DequeueWorkItem(_stpStartInfo.IdleTimeout, _shuttingDownEvent);
551 551
552 return workItem; 552 return workItem;
553 } 553 }
554 554
555 /// <summary> 555 /// <summary>
556 /// Put a new work item in the queue 556 /// Put a new work item in the queue
557 /// </summary> 557 /// </summary>
558 /// <param name="workItem">A work item to queue</param> 558 /// <param name="workItem">A work item to queue</param>
559 internal override void Enqueue(WorkItem workItem) 559 internal override void Enqueue(WorkItem workItem)
560 { 560 {
561 // Make sure the workItem is not null 561 // Make sure the workItem is not null
562 Debug.Assert(null != workItem); 562 Debug.Assert(null != workItem);
563 563
564 IncrementWorkItemsCount(); 564 IncrementWorkItemsCount();
565 565
566 workItem.CanceledSmartThreadPool = _canceledSmartThreadPool; 566 workItem.CanceledSmartThreadPool = _canceledSmartThreadPool;
567 _workItemsQueue.EnqueueWorkItem(workItem); 567 _workItemsQueue.EnqueueWorkItem(workItem);
568 workItem.WorkItemIsQueued(); 568 workItem.WorkItemIsQueued();
569 569
570 // If all the threads are busy then try to create a new one 570 // If all the threads are busy then try to create a new one
571 if (_currentWorkItemsCount > _workerThreads.Count) 571 if (_currentWorkItemsCount > _workerThreads.Count)
572 { 572 {
573 StartThreads(1); 573 StartThreads(1);
574 } 574 }
575 } 575 }
576 576
577 private void IncrementWorkItemsCount() 577 private void IncrementWorkItemsCount()
578 { 578 {
579 _windowsPCs.SampleWorkItems(_workItemsQueue.Count, _workItemsProcessed); 579 _windowsPCs.SampleWorkItems(_workItemsQueue.Count, _workItemsProcessed);
580 _localPCs.SampleWorkItems(_workItemsQueue.Count, _workItemsProcessed); 580 _localPCs.SampleWorkItems(_workItemsQueue.Count, _workItemsProcessed);
581 581
582 int count = Interlocked.Increment(ref _currentWorkItemsCount); 582 int count = Interlocked.Increment(ref _currentWorkItemsCount);
583 //Trace.WriteLine("WorkItemsCount = " + _currentWorkItemsCount.ToString()); 583 //Trace.WriteLine("WorkItemsCount = " + _currentWorkItemsCount.ToString());
584 if (count == 1) 584 if (count == 1)
585 { 585 {
586 IsIdle = false; 586 IsIdle = false;
587 _isIdleWaitHandle.Reset(); 587 _isIdleWaitHandle.Reset();
588 } 588 }
589 } 589 }
590 590
591 private void DecrementWorkItemsCount() 591 private void DecrementWorkItemsCount()
592 { 592 {
593 int count = Interlocked.Decrement(ref _currentWorkItemsCount); 593 int count = Interlocked.Decrement(ref _currentWorkItemsCount);
594 //Trace.WriteLine("WorkItemsCount = " + _currentWorkItemsCount.ToString()); 594 //Trace.WriteLine("WorkItemsCount = " + _currentWorkItemsCount.ToString());
595 if (count == 0) 595 if (count == 0)
596 { 596 {
597 IsIdle = true; 597 IsIdle = true;
598 _isIdleWaitHandle.Set(); 598 _isIdleWaitHandle.Set();
599 } 599 }
600 600
601 Interlocked.Increment(ref _workItemsProcessed); 601 Interlocked.Increment(ref _workItemsProcessed);
602 602
603 if (!_shutdown) 603 if (!_shutdown)
604 { 604 {
605 // The counter counts even if the work item was cancelled 605 // The counter counts even if the work item was cancelled
606 _windowsPCs.SampleWorkItems(_workItemsQueue.Count, _workItemsProcessed); 606 _windowsPCs.SampleWorkItems(_workItemsQueue.Count, _workItemsProcessed);
607 _localPCs.SampleWorkItems(_workItemsQueue.Count, _workItemsProcessed); 607 _localPCs.SampleWorkItems(_workItemsQueue.Count, _workItemsProcessed);
608 } 608 }
609 609
610 } 610 }
611 611
612 internal void RegisterWorkItemsGroup(IWorkItemsGroup workItemsGroup) 612 internal void RegisterWorkItemsGroup(IWorkItemsGroup workItemsGroup)
613 { 613 {
614 _workItemsGroups[workItemsGroup] = workItemsGroup; 614 _workItemsGroups[workItemsGroup] = workItemsGroup;
615 } 615 }
616 616
617 internal void UnregisterWorkItemsGroup(IWorkItemsGroup workItemsGroup) 617 internal void UnregisterWorkItemsGroup(IWorkItemsGroup workItemsGroup)
618 { 618 {
619 if (_workItemsGroups.Contains(workItemsGroup)) 619 if (_workItemsGroups.Contains(workItemsGroup))
620 { 620 {
621 _workItemsGroups.Remove(workItemsGroup); 621 _workItemsGroups.Remove(workItemsGroup);
622 } 622 }
623 } 623 }
624 624
625 /// <summary> 625 /// <summary>
626 /// Inform that the current thread is about to quit or quiting. 626 /// Inform that the current thread is about to quit or quiting.
627 /// The same thread may call this method more than once. 627 /// The same thread may call this method more than once.
628 /// </summary> 628 /// </summary>
629 private void InformCompleted() 629 private void InformCompleted()
630 { 630 {
631 // There is no need to lock the two methods together 631 // There is no need to lock the two methods together
632 // since only the current thread removes itself 632 // since only the current thread removes itself
633 // and the _workerThreads is a synchronized dictionary 633 // and the _workerThreads is a synchronized dictionary
634 if (_workerThreads.Contains(Thread.CurrentThread)) 634 if (_workerThreads.Contains(Thread.CurrentThread))
635 { 635 {
636 _workerThreads.Remove(Thread.CurrentThread); 636 _workerThreads.Remove(Thread.CurrentThread);
637 _windowsPCs.SampleThreads(_workerThreads.Count, _inUseWorkerThreads); 637 _windowsPCs.SampleThreads(_workerThreads.Count, _inUseWorkerThreads);
638 _localPCs.SampleThreads(_workerThreads.Count, _inUseWorkerThreads); 638 _localPCs.SampleThreads(_workerThreads.Count, _inUseWorkerThreads);
639 } 639 }
640 } 640 }
641 641
642 /// <summary> 642 /// <summary>
643 /// Starts new threads 643 /// Starts new threads
644 /// </summary> 644 /// </summary>
645 /// <param name="threadsCount">The number of threads to start</param> 645 /// <param name="threadsCount">The number of threads to start</param>
646 private void StartThreads(int threadsCount) 646 private void StartThreads(int threadsCount)
647 { 647 {
648 if (_isSuspended) 648 if (_isSuspended)
649 { 649 {
650 return; 650 return;
651 } 651 }
652 652
653 lock(_workerThreads.SyncRoot) 653 lock(_workerThreads.SyncRoot)
654 { 654 {
655 // Don't start threads on shut down 655 // Don't start threads on shut down
656 if (_shutdown) 656 if (_shutdown)
657 { 657 {
658 return; 658 return;
659 } 659 }
660 660
661 for(int i = 0; i < threadsCount; ++i) 661 for(int i = 0; i < threadsCount; ++i)
662 { 662 {
663 // Don't create more threads then the upper limit 663 // Don't create more threads then the upper limit
664 if (_workerThreads.Count >= _stpStartInfo.MaxWorkerThreads) 664 if (_workerThreads.Count >= _stpStartInfo.MaxWorkerThreads)
665 { 665 {
666 return; 666 return;
667 } 667 }
668 668
669 // Create a new thread 669 // Create a new thread
670 670
671#if (_SILVERLIGHT) || (WINDOWS_PHONE) 671#if (_SILVERLIGHT) || (WINDOWS_PHONE)
672 Thread workerThread = new Thread(ProcessQueuedItems); 672 Thread workerThread = new Thread(ProcessQueuedItems);
673#else 673#else
674 Thread workerThread = 674 Thread workerThread =
675 _stpStartInfo.MaxStackSize.HasValue 675 _stpStartInfo.MaxStackSize.HasValue
676 ? new Thread(ProcessQueuedItems, _stpStartInfo.MaxStackSize.Value) 676 ? new Thread(ProcessQueuedItems, _stpStartInfo.MaxStackSize.Value)
677 : new Thread(ProcessQueuedItems); 677 : new Thread(ProcessQueuedItems);
678#endif 678#endif
679 // Configure the new thread and start it 679 // Configure the new thread and start it
680 workerThread.Name = "STP " + Name + " Thread #" + _threadCounter; 680 workerThread.Name = "STP " + Name + " Thread #" + _threadCounter;
681 workerThread.IsBackground = _stpStartInfo.AreThreadsBackground; 681 workerThread.IsBackground = _stpStartInfo.AreThreadsBackground;
682 682
683#if !(_SILVERLIGHT) && !(_WINDOWS_CE) && !(WINDOWS_PHONE) 683#if !(_SILVERLIGHT) && !(_WINDOWS_CE) && !(WINDOWS_PHONE)
684 if (_stpStartInfo.ApartmentState != ApartmentState.Unknown) 684 if (_stpStartInfo.ApartmentState != ApartmentState.Unknown)
685 { 685 {
686 workerThread.SetApartmentState(_stpStartInfo.ApartmentState); 686 workerThread.SetApartmentState(_stpStartInfo.ApartmentState);
687 } 687 }
688#endif 688#endif
689 689
690#if !(_SILVERLIGHT) && !(WINDOWS_PHONE) 690#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
691 workerThread.Priority = _stpStartInfo.ThreadPriority; 691 workerThread.Priority = _stpStartInfo.ThreadPriority;
692#endif 692#endif
693 workerThread.Start(); 693 workerThread.Start();
694 ++_threadCounter; 694 ++_threadCounter;
695 695
696 // Add it to the dictionary and update its creation time. 696 // Add it to the dictionary and update its creation time.
697 _workerThreads[workerThread] = new ThreadEntry(this); 697 _workerThreads[workerThread] = new ThreadEntry(this);
698 698
699 _windowsPCs.SampleThreads(_workerThreads.Count, _inUseWorkerThreads); 699 _windowsPCs.SampleThreads(_workerThreads.Count, _inUseWorkerThreads);
700 _localPCs.SampleThreads(_workerThreads.Count, _inUseWorkerThreads); 700 _localPCs.SampleThreads(_workerThreads.Count, _inUseWorkerThreads);
701 } 701 }
702 } 702 }
703 } 703 }
704 704
705 /// <summary> 705 /// <summary>
706 /// A worker thread method that processes work items from the work items queue. 706 /// A worker thread method that processes work items from the work items queue.
707 /// </summary> 707 /// </summary>
708 private void ProcessQueuedItems() 708 private void ProcessQueuedItems()
709 { 709 {
710 // Keep the entry of the dictionary as thread's variable to avoid the synchronization locks 710 // Keep the entry of the dictionary as thread's variable to avoid the synchronization locks
711 // of the dictionary. 711 // of the dictionary.
712 CurrentThreadEntry = _workerThreads[Thread.CurrentThread]; 712 CurrentThreadEntry = _workerThreads[Thread.CurrentThread];
713 713
714 FireOnThreadInitialization(); 714 FireOnThreadInitialization();
715 715
716 try 716 try
717 { 717 {
718 bool bInUseWorkerThreadsWasIncremented = false; 718 bool bInUseWorkerThreadsWasIncremented = false;
719 719
720 // Process until shutdown. 720 // Process until shutdown.
721 while(!_shutdown) 721 while(!_shutdown)
722 { 722 {
723 // Update the last time this thread was seen alive. 723 // Update the last time this thread was seen alive.
724 // It's good for debugging. 724 // It's good for debugging.
725 CurrentThreadEntry.IAmAlive(); 725 CurrentThreadEntry.IAmAlive();
726 726
727 // The following block handles the when the MaxWorkerThreads has been 727 // The following block handles the when the MaxWorkerThreads has been
728 // incremented by the user at run-time. 728 // incremented by the user at run-time.
729 // Double lock for quit. 729 // Double lock for quit.
730 if (_workerThreads.Count > _stpStartInfo.MaxWorkerThreads) 730 if (_workerThreads.Count > _stpStartInfo.MaxWorkerThreads)
731 { 731 {
732 lock (_workerThreads.SyncRoot) 732 lock (_workerThreads.SyncRoot)
733 { 733 {
734 if (_workerThreads.Count > _stpStartInfo.MaxWorkerThreads) 734 if (_workerThreads.Count > _stpStartInfo.MaxWorkerThreads)
735 { 735 {
736 // Inform that the thread is quiting and then quit. 736 // Inform that the thread is quiting and then quit.
737 // This method must be called within this lock or else 737 // This method must be called within this lock or else
738 // more threads will quit and the thread pool will go 738 // more threads will quit and the thread pool will go
739 // below the lower limit. 739 // below the lower limit.
740 InformCompleted(); 740 InformCompleted();
741 break; 741 break;
742 } 742 }
743 } 743 }
744 } 744 }
745 745
746 // Wait for a work item, shutdown, or timeout 746 // Wait for a work item, shutdown, or timeout
747 WorkItem workItem = Dequeue(); 747 WorkItem workItem = Dequeue();
748 748
749 // Update the last time this thread was seen alive. 749 // Update the last time this thread was seen alive.
750 // It's good for debugging. 750 // It's good for debugging.
751 CurrentThreadEntry.IAmAlive(); 751 CurrentThreadEntry.IAmAlive();
752 752
753 // On timeout or shut down. 753 // On timeout or shut down.
754 if (null == workItem) 754 if (null == workItem)
755 { 755 {
756 // Double lock for quit. 756 // Double lock for quit.
757 if (_workerThreads.Count > _stpStartInfo.MinWorkerThreads) 757 if (_workerThreads.Count > _stpStartInfo.MinWorkerThreads)
758 { 758 {
759 lock(_workerThreads.SyncRoot) 759 lock(_workerThreads.SyncRoot)
760 { 760 {
761 if (_workerThreads.Count > _stpStartInfo.MinWorkerThreads) 761 if (_workerThreads.Count > _stpStartInfo.MinWorkerThreads)
762 { 762 {
763 // Inform that the thread is quiting and then quit. 763 // Inform that the thread is quiting and then quit.
764 // This method must be called within this lock or else 764 // This method must be called within this lock or else
765 // more threads will quit and the thread pool will go 765 // more threads will quit and the thread pool will go
766 // below the lower limit. 766 // below the lower limit.
767 InformCompleted(); 767 InformCompleted();
768 break; 768 break;
769 } 769 }
770 } 770 }
771 } 771 }
772 } 772 }
773 773
774 // If we didn't quit then skip to the next iteration. 774 // If we didn't quit then skip to the next iteration.
775 if (null == workItem) 775 if (null == workItem)
776 { 776 {
777 continue; 777 continue;
778 } 778 }
779 779
780 try 780 try
781 { 781 {
782 // Initialize the value to false 782 // Initialize the value to false
783 bInUseWorkerThreadsWasIncremented = false; 783 bInUseWorkerThreadsWasIncremented = false;
784 784
785 // Set the Current Work Item of the thread. 785 // Set the Current Work Item of the thread.
786 // Store the Current Work Item before the workItem.StartingWorkItem() is called, 786 // Store the Current Work Item before the workItem.StartingWorkItem() is called,
787 // so WorkItem.Cancel can work when the work item is between InQueue and InProgress 787 // so WorkItem.Cancel can work when the work item is between InQueue and InProgress
788 // states. 788 // states.
789 // If the work item has been cancelled BEFORE the workItem.StartingWorkItem() 789 // If the work item has been cancelled BEFORE the workItem.StartingWorkItem()
790 // (work item is in InQueue state) then workItem.StartingWorkItem() will return false. 790 // (work item is in InQueue state) then workItem.StartingWorkItem() will return false.
791 // If the work item has been cancelled AFTER the workItem.StartingWorkItem() then 791 // If the work item has been cancelled AFTER the workItem.StartingWorkItem() then
792 // (work item is in InProgress state) then the thread will be aborted 792 // (work item is in InProgress state) then the thread will be aborted
793 CurrentThreadEntry.CurrentWorkItem = workItem; 793 CurrentThreadEntry.CurrentWorkItem = workItem;
794 794
795 // Change the state of the work item to 'in progress' if possible. 795 // Change the state of the work item to 'in progress' if possible.
796 // We do it here so if the work item has been canceled we won't 796 // We do it here so if the work item has been canceled we won't
797 // increment the _inUseWorkerThreads. 797 // increment the _inUseWorkerThreads.
798 // The cancel mechanism doesn't delete items from the queue, 798 // The cancel mechanism doesn't delete items from the queue,
799 // it marks the work item as canceled, and when the work item 799 // it marks the work item as canceled, and when the work item
800 // is dequeued, we just skip it. 800 // is dequeued, we just skip it.
801 // If the post execute of work item is set to always or to 801 // If the post execute of work item is set to always or to
802 // call when the work item is canceled then the StartingWorkItem() 802 // call when the work item is canceled then the StartingWorkItem()
803 // will return true, so the post execute can run. 803 // will return true, so the post execute can run.
804 if (!workItem.StartingWorkItem()) 804 if (!workItem.StartingWorkItem())
805 { 805 {
806 continue; 806 continue;
807 } 807 }
808 808
809 // Execute the callback. Make sure to accurately 809 // Execute the callback. Make sure to accurately
810 // record how many callbacks are currently executing. 810 // record how many callbacks are currently executing.
811 int inUseWorkerThreads = Interlocked.Increment(ref _inUseWorkerThreads); 811 int inUseWorkerThreads = Interlocked.Increment(ref _inUseWorkerThreads);
812 _windowsPCs.SampleThreads(_workerThreads.Count, inUseWorkerThreads); 812 _windowsPCs.SampleThreads(_workerThreads.Count, inUseWorkerThreads);
813 _localPCs.SampleThreads(_workerThreads.Count, inUseWorkerThreads); 813 _localPCs.SampleThreads(_workerThreads.Count, inUseWorkerThreads);
814 814
815 // Mark that the _inUseWorkerThreads incremented, so in the finally{} 815 // Mark that the _inUseWorkerThreads incremented, so in the finally{}
816 // statement we will decrement it correctly. 816 // statement we will decrement it correctly.
817 bInUseWorkerThreadsWasIncremented = true; 817 bInUseWorkerThreadsWasIncremented = true;
818 818
819 workItem.FireWorkItemStarted(); 819 workItem.FireWorkItemStarted();
820 820
821 ExecuteWorkItem(workItem); 821 ExecuteWorkItem(workItem);
822 } 822 }
823 catch(Exception ex) 823 catch(Exception ex)
824 { 824 {
825 ex.GetHashCode(); 825 ex.GetHashCode();
826 // Do nothing 826 // Do nothing
827 } 827 }
828 finally 828 finally
829 { 829 {
830 workItem.DisposeOfState(); 830 workItem.DisposeOfState();
831 831
832 // Set the CurrentWorkItem to null, since we 832 // Set the CurrentWorkItem to null, since we
833 // no longer run user's code. 833 // no longer run user's code.
834 CurrentThreadEntry.CurrentWorkItem = null; 834 CurrentThreadEntry.CurrentWorkItem = null;
835 835
836 // Decrement the _inUseWorkerThreads only if we had 836 // Decrement the _inUseWorkerThreads only if we had
837 // incremented it. Note the cancelled work items don't 837 // incremented it. Note the cancelled work items don't
838 // increment _inUseWorkerThreads. 838 // increment _inUseWorkerThreads.
839 if (bInUseWorkerThreadsWasIncremented) 839 if (bInUseWorkerThreadsWasIncremented)
840 { 840 {
841 int inUseWorkerThreads = Interlocked.Decrement(ref _inUseWorkerThreads); 841 int inUseWorkerThreads = Interlocked.Decrement(ref _inUseWorkerThreads);
842 _windowsPCs.SampleThreads(_workerThreads.Count, inUseWorkerThreads); 842 _windowsPCs.SampleThreads(_workerThreads.Count, inUseWorkerThreads);
843 _localPCs.SampleThreads(_workerThreads.Count, inUseWorkerThreads); 843 _localPCs.SampleThreads(_workerThreads.Count, inUseWorkerThreads);
844 } 844 }
845 845
846 // Notify that the work item has been completed. 846 // Notify that the work item has been completed.
847 // WorkItemsGroup may enqueue their next work item. 847 // WorkItemsGroup may enqueue their next work item.
848 workItem.FireWorkItemCompleted(); 848 workItem.FireWorkItemCompleted();
849 849
850 // Decrement the number of work items here so the idle 850 // Decrement the number of work items here so the idle
851 // ManualResetEvent won't fluctuate. 851 // ManualResetEvent won't fluctuate.
852 DecrementWorkItemsCount(); 852 DecrementWorkItemsCount();
853 } 853 }
854 } 854 }
855 } 855 }
856 catch(ThreadAbortException tae) 856 catch(ThreadAbortException tae)
857 { 857 {
858 tae.GetHashCode(); 858 tae.GetHashCode();
859 // Handle the abort exception gracfully. 859 // Handle the abort exception gracfully.
860#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE) 860#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
861 Thread.ResetAbort(); 861 Thread.ResetAbort();
862#endif 862#endif
863 } 863 }
864 catch(Exception e) 864 catch(Exception e)
865 { 865 {
866 Debug.Assert(null != e); 866 Debug.Assert(null != e);
867 } 867 }
868 finally 868 finally
869 { 869 {
870 InformCompleted(); 870 InformCompleted();
871 FireOnThreadTermination(); 871 FireOnThreadTermination();
872 } 872 }
873 } 873 }
874 874
875 private void ExecuteWorkItem(WorkItem workItem) 875 private void ExecuteWorkItem(WorkItem workItem)
876 { 876 {
877 _windowsPCs.SampleWorkItemsWaitTime(workItem.WaitingTime); 877 _windowsPCs.SampleWorkItemsWaitTime(workItem.WaitingTime);
878 _localPCs.SampleWorkItemsWaitTime(workItem.WaitingTime); 878 _localPCs.SampleWorkItemsWaitTime(workItem.WaitingTime);
879 try 879 try
880 { 880 {
881 workItem.Execute(); 881 workItem.Execute();
882 } 882 }
883 finally 883 finally
884 { 884 {
885 _windowsPCs.SampleWorkItemsProcessTime(workItem.ProcessTime); 885 _windowsPCs.SampleWorkItemsProcessTime(workItem.ProcessTime);
886 _localPCs.SampleWorkItemsProcessTime(workItem.ProcessTime); 886 _localPCs.SampleWorkItemsProcessTime(workItem.ProcessTime);
887 } 887 }
888 } 888 }
889 889
890 890
891 #endregion 891 #endregion
892 892
893 #region Public Methods 893 #region Public Methods
894 894
895 private void ValidateWaitForIdle() 895 private void ValidateWaitForIdle()
896 { 896 {
897 if (null != CurrentThreadEntry && CurrentThreadEntry.AssociatedSmartThreadPool == this) 897 if (null != CurrentThreadEntry && CurrentThreadEntry.AssociatedSmartThreadPool == this)
898 { 898 {
899 throw new NotSupportedException( 899 throw new NotSupportedException(
900 "WaitForIdle cannot be called from a thread on its SmartThreadPool, it causes a deadlock"); 900 "WaitForIdle cannot be called from a thread on its SmartThreadPool, it causes a deadlock");
901 } 901 }
902 } 902 }
903 903
904 internal static void ValidateWorkItemsGroupWaitForIdle(IWorkItemsGroup workItemsGroup) 904 internal static void ValidateWorkItemsGroupWaitForIdle(IWorkItemsGroup workItemsGroup)
905 { 905 {
906 if (null == CurrentThreadEntry) 906 if (null == CurrentThreadEntry)
907 { 907 {
908 return; 908 return;
909 } 909 }
910 910
911 WorkItem workItem = CurrentThreadEntry.CurrentWorkItem; 911 WorkItem workItem = CurrentThreadEntry.CurrentWorkItem;
912 ValidateWorkItemsGroupWaitForIdleImpl(workItemsGroup, workItem); 912 ValidateWorkItemsGroupWaitForIdleImpl(workItemsGroup, workItem);
913 if ((null != workItemsGroup) && 913 if ((null != workItemsGroup) &&
914 (null != workItem) && 914 (null != workItem) &&
915 CurrentThreadEntry.CurrentWorkItem.WasQueuedBy(workItemsGroup)) 915 CurrentThreadEntry.CurrentWorkItem.WasQueuedBy(workItemsGroup))
916 { 916 {
917 throw new NotSupportedException("WaitForIdle cannot be called from a thread on its SmartThreadPool, it causes a deadlock"); 917 throw new NotSupportedException("WaitForIdle cannot be called from a thread on its SmartThreadPool, it causes a deadlock");
918 } 918 }
919 } 919 }
920 920
921 [MethodImpl(MethodImplOptions.NoInlining)] 921 [MethodImpl(MethodImplOptions.NoInlining)]
922 private static void ValidateWorkItemsGroupWaitForIdleImpl(IWorkItemsGroup workItemsGroup, WorkItem workItem) 922 private static void ValidateWorkItemsGroupWaitForIdleImpl(IWorkItemsGroup workItemsGroup, WorkItem workItem)
923 { 923 {
924 if ((null != workItemsGroup) && 924 if ((null != workItemsGroup) &&
925 (null != workItem) && 925 (null != workItem) &&
926 workItem.WasQueuedBy(workItemsGroup)) 926 workItem.WasQueuedBy(workItemsGroup))
927 { 927 {
928 throw new NotSupportedException("WaitForIdle cannot be called from a thread on its SmartThreadPool, it causes a deadlock"); 928 throw new NotSupportedException("WaitForIdle cannot be called from a thread on its SmartThreadPool, it causes a deadlock");
929 } 929 }
930 } 930 }
931 931
932 /// <summary> 932 /// <summary>
933 /// Force the SmartThreadPool to shutdown 933 /// Force the SmartThreadPool to shutdown
934 /// </summary> 934 /// </summary>
935 public void Shutdown() 935 public void Shutdown()
936 { 936 {
937 Shutdown(true, 0); 937 Shutdown(true, 0);
938 } 938 }
939 939
940 /// <summary> 940 /// <summary>
941 /// Force the SmartThreadPool to shutdown with timeout 941 /// Force the SmartThreadPool to shutdown with timeout
942 /// </summary> 942 /// </summary>
943 public void Shutdown(bool forceAbort, TimeSpan timeout) 943 public void Shutdown(bool forceAbort, TimeSpan timeout)
944 { 944 {
945 Shutdown(forceAbort, (int)timeout.TotalMilliseconds); 945 Shutdown(forceAbort, (int)timeout.TotalMilliseconds);
946 } 946 }
947 947
948 /// <summary> 948 /// <summary>
949 /// Empties the queue of work items and abort the threads in the pool. 949 /// Empties the queue of work items and abort the threads in the pool.
950 /// </summary> 950 /// </summary>
951 public void Shutdown(bool forceAbort, int millisecondsTimeout) 951 public void Shutdown(bool forceAbort, int millisecondsTimeout)
952 { 952 {
953 ValidateNotDisposed(); 953 ValidateNotDisposed();
954 954
955 ISTPInstancePerformanceCounters pcs = _windowsPCs; 955 ISTPInstancePerformanceCounters pcs = _windowsPCs;
956 956
957 if (NullSTPInstancePerformanceCounters.Instance != _windowsPCs) 957 if (NullSTPInstancePerformanceCounters.Instance != _windowsPCs)
958 { 958 {
959 // Set the _pcs to "null" to stop updating the performance 959 // Set the _pcs to "null" to stop updating the performance
960 // counters 960 // counters
961 _windowsPCs = NullSTPInstancePerformanceCounters.Instance; 961 _windowsPCs = NullSTPInstancePerformanceCounters.Instance;
962 962
963 pcs.Dispose(); 963 pcs.Dispose();
964 } 964 }
965 965
966 Thread [] threads; 966 Thread [] threads;
967 lock(_workerThreads.SyncRoot) 967 lock(_workerThreads.SyncRoot)
968 { 968 {
969 // Shutdown the work items queue 969 // Shutdown the work items queue
970 _workItemsQueue.Dispose(); 970 _workItemsQueue.Dispose();
971 971
972 // Signal the threads to exit 972 // Signal the threads to exit
973 _shutdown = true; 973 _shutdown = true;
974 _shuttingDownEvent.Set(); 974 _shuttingDownEvent.Set();
975 975
976 // Make a copy of the threads' references in the pool 976 // Make a copy of the threads' references in the pool
977 threads = new Thread [_workerThreads.Count]; 977 threads = new Thread [_workerThreads.Count];
978 _workerThreads.Keys.CopyTo(threads, 0); 978 _workerThreads.Keys.CopyTo(threads, 0);
979 } 979 }
980 980
981 int millisecondsLeft = millisecondsTimeout; 981 int millisecondsLeft = millisecondsTimeout;
982 Stopwatch stopwatch = Stopwatch.StartNew(); 982 Stopwatch stopwatch = Stopwatch.StartNew();
983 //DateTime start = DateTime.UtcNow; 983 //DateTime start = DateTime.UtcNow;
984 bool waitInfinitely = (Timeout.Infinite == millisecondsTimeout); 984 bool waitInfinitely = (Timeout.Infinite == millisecondsTimeout);
985 bool timeout = false; 985 bool timeout = false;
986 986
987 // Each iteration we update the time left for the timeout. 987 // Each iteration we update the time left for the timeout.
988 foreach(Thread thread in threads) 988 foreach(Thread thread in threads)
989 { 989 {
990 // Join don't work with negative numbers 990 // Join don't work with negative numbers
991 if (!waitInfinitely && (millisecondsLeft < 0)) 991 if (!waitInfinitely && (millisecondsLeft < 0))
992 { 992 {
993 timeout = true; 993 timeout = true;
994 break; 994 break;
995 } 995 }
996 996
997 // Wait for the thread to terminate 997 // Wait for the thread to terminate
998 bool success = thread.Join(millisecondsLeft); 998 bool success = thread.Join(millisecondsLeft);
999 if(!success) 999 if(!success)
1000 { 1000 {
1001 timeout = true; 1001 timeout = true;
1002 break; 1002 break;
1003 } 1003 }
1004 1004
1005 if(!waitInfinitely) 1005 if(!waitInfinitely)
1006 { 1006 {
1007 // Update the time left to wait 1007 // Update the time left to wait
1008 //TimeSpan ts = DateTime.UtcNow - start; 1008 //TimeSpan ts = DateTime.UtcNow - start;
1009 millisecondsLeft = millisecondsTimeout - (int)stopwatch.ElapsedMilliseconds; 1009 millisecondsLeft = millisecondsTimeout - (int)stopwatch.ElapsedMilliseconds;
1010 } 1010 }
1011 } 1011 }
1012 1012
1013 if (timeout && forceAbort) 1013 if (timeout && forceAbort)
1014 { 1014 {
1015 // Abort the threads in the pool 1015 // Abort the threads in the pool
1016 foreach(Thread thread in threads) 1016 foreach(Thread thread in threads)
1017 { 1017 {
1018 1018
1019 if ((thread != null) 1019 if ((thread != null)
1020#if !(_WINDOWS_CE) 1020#if !(_WINDOWS_CE)
1021 && thread.IsAlive 1021 && thread.IsAlive
1022#endif 1022#endif
1023 ) 1023 )
1024 { 1024 {
1025 try 1025 try
1026 { 1026 {
1027 thread.Abort(); // Shutdown 1027 thread.Abort(); // Shutdown
1028 } 1028 }
1029 catch(SecurityException e) 1029 catch(SecurityException e)
1030 { 1030 {
1031 e.GetHashCode(); 1031 e.GetHashCode();
1032 } 1032 }
1033 catch(ThreadStateException ex) 1033 catch(ThreadStateException ex)
1034 { 1034 {
1035 ex.GetHashCode(); 1035 ex.GetHashCode();
1036 // In case the thread has been terminated 1036 // In case the thread has been terminated
1037 // after the check if it is alive. 1037 // after the check if it is alive.
1038 } 1038 }
1039 } 1039 }
1040 } 1040 }
1041 } 1041 }
1042 } 1042 }
1043 1043
1044 /// <summary> 1044 /// <summary>
1045 /// Wait for all work items to complete 1045 /// Wait for all work items to complete
1046 /// </summary> 1046 /// </summary>
1047 /// <param name="waitableResults">Array of work item result objects</param> 1047 /// <param name="waitableResults">Array of work item result objects</param>
1048 /// <returns> 1048 /// <returns>
1049 /// true when every work item in workItemResults has completed; otherwise false. 1049 /// true when every work item in workItemResults has completed; otherwise false.
1050 /// </returns> 1050 /// </returns>
1051 public static bool WaitAll( 1051 public static bool WaitAll(
1052 IWaitableResult [] waitableResults) 1052 IWaitableResult [] waitableResults)
1053 { 1053 {
1054 return WaitAll(waitableResults, Timeout.Infinite, true); 1054 return WaitAll(waitableResults, Timeout.Infinite, true);
1055 } 1055 }
1056 1056
1057 /// <summary> 1057 /// <summary>
1058 /// Wait for all work items to complete 1058 /// Wait for all work items to complete
1059 /// </summary> 1059 /// </summary>
1060 /// <param name="waitableResults">Array of work item result objects</param> 1060 /// <param name="waitableResults">Array of work item result objects</param>
1061 /// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param> 1061 /// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param>
1062 /// <param name="exitContext"> 1062 /// <param name="exitContext">
1063 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 1063 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
1064 /// </param> 1064 /// </param>
1065 /// <returns> 1065 /// <returns>
1066 /// true when every work item in workItemResults has completed; otherwise false. 1066 /// true when every work item in workItemResults has completed; otherwise false.
1067 /// </returns> 1067 /// </returns>
1068 public static bool WaitAll( 1068 public static bool WaitAll(
1069 IWaitableResult [] waitableResults, 1069 IWaitableResult [] waitableResults,
1070 TimeSpan timeout, 1070 TimeSpan timeout,
1071 bool exitContext) 1071 bool exitContext)
1072 { 1072 {
1073 return WaitAll(waitableResults, (int)timeout.TotalMilliseconds, exitContext); 1073 return WaitAll(waitableResults, (int)timeout.TotalMilliseconds, exitContext);
1074 } 1074 }
1075 1075
1076 /// <summary> 1076 /// <summary>
1077 /// Wait for all work items to complete 1077 /// Wait for all work items to complete
1078 /// </summary> 1078 /// </summary>
1079 /// <param name="waitableResults">Array of work item result objects</param> 1079 /// <param name="waitableResults">Array of work item result objects</param>
1080 /// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param> 1080 /// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param>
1081 /// <param name="exitContext"> 1081 /// <param name="exitContext">
1082 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 1082 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
1083 /// </param> 1083 /// </param>
1084 /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param> 1084 /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
1085 /// <returns> 1085 /// <returns>
1086 /// true when every work item in workItemResults has completed; otherwise false. 1086 /// true when every work item in workItemResults has completed; otherwise false.
1087 /// </returns> 1087 /// </returns>
1088 public static bool WaitAll( 1088 public static bool WaitAll(
1089 IWaitableResult[] waitableResults, 1089 IWaitableResult[] waitableResults,
1090 TimeSpan timeout, 1090 TimeSpan timeout,
1091 bool exitContext, 1091 bool exitContext,
1092 WaitHandle cancelWaitHandle) 1092 WaitHandle cancelWaitHandle)
1093 { 1093 {
1094 return WaitAll(waitableResults, (int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle); 1094 return WaitAll(waitableResults, (int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle);
1095 } 1095 }
1096 1096
1097 /// <summary> 1097 /// <summary>
1098 /// Wait for all work items to complete 1098 /// Wait for all work items to complete
1099 /// </summary> 1099 /// </summary>
1100 /// <param name="waitableResults">Array of work item result objects</param> 1100 /// <param name="waitableResults">Array of work item result objects</param>
1101 /// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param> 1101 /// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
1102 /// <param name="exitContext"> 1102 /// <param name="exitContext">
1103 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 1103 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
1104 /// </param> 1104 /// </param>
1105 /// <returns> 1105 /// <returns>
1106 /// true when every work item in workItemResults has completed; otherwise false. 1106 /// true when every work item in workItemResults has completed; otherwise false.
1107 /// </returns> 1107 /// </returns>
1108 public static bool WaitAll( 1108 public static bool WaitAll(
1109 IWaitableResult [] waitableResults, 1109 IWaitableResult [] waitableResults,
1110 int millisecondsTimeout, 1110 int millisecondsTimeout,
1111 bool exitContext) 1111 bool exitContext)
1112 { 1112 {
1113 return WorkItem.WaitAll(waitableResults, millisecondsTimeout, exitContext, null); 1113 return WorkItem.WaitAll(waitableResults, millisecondsTimeout, exitContext, null);
1114 } 1114 }
1115 1115
1116 /// <summary> 1116 /// <summary>
1117 /// Wait for all work items to complete 1117 /// Wait for all work items to complete
1118 /// </summary> 1118 /// </summary>
1119 /// <param name="waitableResults">Array of work item result objects</param> 1119 /// <param name="waitableResults">Array of work item result objects</param>
1120 /// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param> 1120 /// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
1121 /// <param name="exitContext"> 1121 /// <param name="exitContext">
1122 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 1122 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
1123 /// </param> 1123 /// </param>
1124 /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param> 1124 /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
1125 /// <returns> 1125 /// <returns>
1126 /// true when every work item in workItemResults has completed; otherwise false. 1126 /// true when every work item in workItemResults has completed; otherwise false.
1127 /// </returns> 1127 /// </returns>
1128 public static bool WaitAll( 1128 public static bool WaitAll(
1129 IWaitableResult[] waitableResults, 1129 IWaitableResult[] waitableResults,
1130 int millisecondsTimeout, 1130 int millisecondsTimeout,
1131 bool exitContext, 1131 bool exitContext,
1132 WaitHandle cancelWaitHandle) 1132 WaitHandle cancelWaitHandle)
1133 { 1133 {
1134 return WorkItem.WaitAll(waitableResults, millisecondsTimeout, exitContext, cancelWaitHandle); 1134 return WorkItem.WaitAll(waitableResults, millisecondsTimeout, exitContext, cancelWaitHandle);
1135 } 1135 }
1136 1136
1137 1137
1138 /// <summary> 1138 /// <summary>
1139 /// Waits for any of the work items in the specified array to complete, cancel, or timeout 1139 /// Waits for any of the work items in the specified array to complete, cancel, or timeout
1140 /// </summary> 1140 /// </summary>
1141 /// <param name="waitableResults">Array of work item result objects</param> 1141 /// <param name="waitableResults">Array of work item result objects</param>
1142 /// <returns> 1142 /// <returns>
1143 /// The array index of the work item result that satisfied the wait, or WaitTimeout if any of the work items has been canceled. 1143 /// The array index of the work item result that satisfied the wait, or WaitTimeout if any of the work items has been canceled.
1144 /// </returns> 1144 /// </returns>
1145 public static int WaitAny( 1145 public static int WaitAny(
1146 IWaitableResult [] waitableResults) 1146 IWaitableResult [] waitableResults)
1147 { 1147 {
1148 return WaitAny(waitableResults, Timeout.Infinite, true); 1148 return WaitAny(waitableResults, Timeout.Infinite, true);
1149 } 1149 }
1150 1150
1151 /// <summary> 1151 /// <summary>
1152 /// Waits for any of the work items in the specified array to complete, cancel, or timeout 1152 /// Waits for any of the work items in the specified array to complete, cancel, or timeout
1153 /// </summary> 1153 /// </summary>
1154 /// <param name="waitableResults">Array of work item result objects</param> 1154 /// <param name="waitableResults">Array of work item result objects</param>
1155 /// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param> 1155 /// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param>
1156 /// <param name="exitContext"> 1156 /// <param name="exitContext">
1157 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 1157 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
1158 /// </param> 1158 /// </param>
1159 /// <returns> 1159 /// <returns>
1160 /// The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled. 1160 /// The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled.
1161 /// </returns> 1161 /// </returns>
1162 public static int WaitAny( 1162 public static int WaitAny(
1163 IWaitableResult[] waitableResults, 1163 IWaitableResult[] waitableResults,
1164 TimeSpan timeout, 1164 TimeSpan timeout,
1165 bool exitContext) 1165 bool exitContext)
1166 { 1166 {
1167 return WaitAny(waitableResults, (int)timeout.TotalMilliseconds, exitContext); 1167 return WaitAny(waitableResults, (int)timeout.TotalMilliseconds, exitContext);
1168 } 1168 }
1169 1169
1170 /// <summary> 1170 /// <summary>
1171 /// Waits for any of the work items in the specified array to complete, cancel, or timeout 1171 /// Waits for any of the work items in the specified array to complete, cancel, or timeout
1172 /// </summary> 1172 /// </summary>
1173 /// <param name="waitableResults">Array of work item result objects</param> 1173 /// <param name="waitableResults">Array of work item result objects</param>
1174 /// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param> 1174 /// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param>
1175 /// <param name="exitContext"> 1175 /// <param name="exitContext">
1176 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 1176 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
1177 /// </param> 1177 /// </param>
1178 /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param> 1178 /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
1179 /// <returns> 1179 /// <returns>
1180 /// The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled. 1180 /// The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled.
1181 /// </returns> 1181 /// </returns>
1182 public static int WaitAny( 1182 public static int WaitAny(
1183 IWaitableResult [] waitableResults, 1183 IWaitableResult [] waitableResults,
1184 TimeSpan timeout, 1184 TimeSpan timeout,
1185 bool exitContext, 1185 bool exitContext,
1186 WaitHandle cancelWaitHandle) 1186 WaitHandle cancelWaitHandle)
1187 { 1187 {
1188 return WaitAny(waitableResults, (int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle); 1188 return WaitAny(waitableResults, (int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle);
1189 } 1189 }
1190 1190
1191 /// <summary> 1191 /// <summary>
1192 /// Waits for any of the work items in the specified array to complete, cancel, or timeout 1192 /// Waits for any of the work items in the specified array to complete, cancel, or timeout
1193 /// </summary> 1193 /// </summary>
1194 /// <param name="waitableResults">Array of work item result objects</param> 1194 /// <param name="waitableResults">Array of work item result objects</param>
1195 /// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param> 1195 /// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
1196 /// <param name="exitContext"> 1196 /// <param name="exitContext">
1197 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 1197 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
1198 /// </param> 1198 /// </param>
1199 /// <returns> 1199 /// <returns>
1200 /// The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled. 1200 /// The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled.
1201 /// </returns> 1201 /// </returns>
1202 public static int WaitAny( 1202 public static int WaitAny(
1203 IWaitableResult [] waitableResults, 1203 IWaitableResult [] waitableResults,
1204 int millisecondsTimeout, 1204 int millisecondsTimeout,
1205 bool exitContext) 1205 bool exitContext)
1206 { 1206 {
1207 return WorkItem.WaitAny(waitableResults, millisecondsTimeout, exitContext, null); 1207 return WorkItem.WaitAny(waitableResults, millisecondsTimeout, exitContext, null);
1208 } 1208 }
1209 1209
1210 /// <summary> 1210 /// <summary>
1211 /// Waits for any of the work items in the specified array to complete, cancel, or timeout 1211 /// Waits for any of the work items in the specified array to complete, cancel, or timeout
1212 /// </summary> 1212 /// </summary>
1213 /// <param name="waitableResults">Array of work item result objects</param> 1213 /// <param name="waitableResults">Array of work item result objects</param>
1214 /// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param> 1214 /// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
1215 /// <param name="exitContext"> 1215 /// <param name="exitContext">
1216 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 1216 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
1217 /// </param> 1217 /// </param>
1218 /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param> 1218 /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
1219 /// <returns> 1219 /// <returns>
1220 /// The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled. 1220 /// The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled.
1221 /// </returns> 1221 /// </returns>
1222 public static int WaitAny( 1222 public static int WaitAny(
1223 IWaitableResult [] waitableResults, 1223 IWaitableResult [] waitableResults,
1224 int millisecondsTimeout, 1224 int millisecondsTimeout,
1225 bool exitContext, 1225 bool exitContext,
1226 WaitHandle cancelWaitHandle) 1226 WaitHandle cancelWaitHandle)
1227 { 1227 {
1228 return WorkItem.WaitAny(waitableResults, millisecondsTimeout, exitContext, cancelWaitHandle); 1228 return WorkItem.WaitAny(waitableResults, millisecondsTimeout, exitContext, cancelWaitHandle);
1229 } 1229 }
1230 1230
1231 /// <summary> 1231 /// <summary>
1232 /// Creates a new WorkItemsGroup. 1232 /// Creates a new WorkItemsGroup.
1233 /// </summary> 1233 /// </summary>
1234 /// <param name="concurrency">The number of work items that can be run concurrently</param> 1234 /// <param name="concurrency">The number of work items that can be run concurrently</param>
1235 /// <returns>A reference to the WorkItemsGroup</returns> 1235 /// <returns>A reference to the WorkItemsGroup</returns>
1236 public IWorkItemsGroup CreateWorkItemsGroup(int concurrency) 1236 public IWorkItemsGroup CreateWorkItemsGroup(int concurrency)
1237 { 1237 {
1238 IWorkItemsGroup workItemsGroup = new WorkItemsGroup(this, concurrency, _stpStartInfo); 1238 IWorkItemsGroup workItemsGroup = new WorkItemsGroup(this, concurrency, _stpStartInfo);
1239 return workItemsGroup; 1239 return workItemsGroup;
1240 } 1240 }
1241 1241
1242 /// <summary> 1242 /// <summary>
1243 /// Creates a new WorkItemsGroup. 1243 /// Creates a new WorkItemsGroup.
1244 /// </summary> 1244 /// </summary>
1245 /// <param name="concurrency">The number of work items that can be run concurrently</param> 1245 /// <param name="concurrency">The number of work items that can be run concurrently</param>
1246 /// <param name="wigStartInfo">A WorkItemsGroup configuration that overrides the default behavior</param> 1246 /// <param name="wigStartInfo">A WorkItemsGroup configuration that overrides the default behavior</param>
1247 /// <returns>A reference to the WorkItemsGroup</returns> 1247 /// <returns>A reference to the WorkItemsGroup</returns>
1248 public IWorkItemsGroup CreateWorkItemsGroup(int concurrency, WIGStartInfo wigStartInfo) 1248 public IWorkItemsGroup CreateWorkItemsGroup(int concurrency, WIGStartInfo wigStartInfo)
1249 { 1249 {
1250 IWorkItemsGroup workItemsGroup = new WorkItemsGroup(this, concurrency, wigStartInfo); 1250 IWorkItemsGroup workItemsGroup = new WorkItemsGroup(this, concurrency, wigStartInfo);
1251 return workItemsGroup; 1251 return workItemsGroup;
1252 } 1252 }
1253 1253
1254 #region Fire Thread's Events 1254 #region Fire Thread's Events
1255 1255
1256 private void FireOnThreadInitialization() 1256 private void FireOnThreadInitialization()
1257 { 1257 {
1258 if (null != _onThreadInitialization) 1258 if (null != _onThreadInitialization)
1259 { 1259 {
1260 foreach (ThreadInitializationHandler tih in _onThreadInitialization.GetInvocationList()) 1260 foreach (ThreadInitializationHandler tih in _onThreadInitialization.GetInvocationList())
1261 { 1261 {
1262 try 1262 try
1263 { 1263 {
1264 tih(); 1264 tih();
1265 } 1265 }
1266 catch (Exception e) 1266 catch (Exception e)
1267 { 1267 {
1268 e.GetHashCode(); 1268 e.GetHashCode();
1269 Debug.Assert(false); 1269 Debug.Assert(false);
1270 throw; 1270 throw;
1271 } 1271 }
1272 } 1272 }
1273 } 1273 }
1274 } 1274 }
1275 1275
1276 private void FireOnThreadTermination() 1276 private void FireOnThreadTermination()
1277 { 1277 {
1278 if (null != _onThreadTermination) 1278 if (null != _onThreadTermination)
1279 { 1279 {
1280 foreach (ThreadTerminationHandler tth in _onThreadTermination.GetInvocationList()) 1280 foreach (ThreadTerminationHandler tth in _onThreadTermination.GetInvocationList())
1281 { 1281 {
1282 try 1282 try
1283 { 1283 {
1284 tth(); 1284 tth();
1285 } 1285 }
1286 catch (Exception e) 1286 catch (Exception e)
1287 { 1287 {
1288 e.GetHashCode(); 1288 e.GetHashCode();
1289 Debug.Assert(false); 1289 Debug.Assert(false);
1290 throw; 1290 throw;
1291 } 1291 }
1292 } 1292 }
1293 } 1293 }
1294 } 1294 }
1295 1295
1296 #endregion 1296 #endregion
1297 1297
1298 /// <summary> 1298 /// <summary>
1299 /// This event is fired when a thread is created. 1299 /// This event is fired when a thread is created.
1300 /// Use it to initialize a thread before the work items use it. 1300 /// Use it to initialize a thread before the work items use it.
1301 /// </summary> 1301 /// </summary>
1302 public event ThreadInitializationHandler OnThreadInitialization 1302 public event ThreadInitializationHandler OnThreadInitialization
1303 { 1303 {
1304 add { _onThreadInitialization += value; } 1304 add { _onThreadInitialization += value; }
1305 remove { _onThreadInitialization -= value; } 1305 remove { _onThreadInitialization -= value; }
1306 } 1306 }
1307 1307
1308 /// <summary> 1308 /// <summary>
1309 /// This event is fired when a thread is terminating. 1309 /// This event is fired when a thread is terminating.
1310 /// Use it for cleanup. 1310 /// Use it for cleanup.
1311 /// </summary> 1311 /// </summary>
1312 public event ThreadTerminationHandler OnThreadTermination 1312 public event ThreadTerminationHandler OnThreadTermination
1313 { 1313 {
1314 add { _onThreadTermination += value; } 1314 add { _onThreadTermination += value; }
1315 remove { _onThreadTermination -= value; } 1315 remove { _onThreadTermination -= value; }
1316 } 1316 }
1317 1317
1318 1318
1319 internal void CancelAbortWorkItemsGroup(WorkItemsGroup wig) 1319 internal void CancelAbortWorkItemsGroup(WorkItemsGroup wig)
1320 { 1320 {
1321 foreach (ThreadEntry threadEntry in _workerThreads.Values) 1321 foreach (ThreadEntry threadEntry in _workerThreads.Values)
1322 { 1322 {
1323 WorkItem workItem = threadEntry.CurrentWorkItem; 1323 WorkItem workItem = threadEntry.CurrentWorkItem;
1324 if (null != workItem && 1324 if (null != workItem &&
1325 workItem.WasQueuedBy(wig) && 1325 workItem.WasQueuedBy(wig) &&
1326 !workItem.IsCanceled) 1326 !workItem.IsCanceled)
1327 { 1327 {
1328 threadEntry.CurrentWorkItem.GetWorkItemResult().Cancel(true); 1328 threadEntry.CurrentWorkItem.GetWorkItemResult().Cancel(true);
1329 } 1329 }
1330 } 1330 }
1331 } 1331 }
1332 1332
1333 1333
1334 1334
1335 #endregion 1335 #endregion
1336 1336
1337 #region Properties 1337 #region Properties
1338 1338
1339 /// <summary> 1339 /// <summary>
1340 /// Get/Set the lower limit of threads in the pool. 1340 /// Get/Set the lower limit of threads in the pool.
1341 /// </summary> 1341 /// </summary>
1342 public int MinThreads 1342 public int MinThreads
1343 { 1343 {
1344 get 1344 get
1345 { 1345 {
1346 ValidateNotDisposed(); 1346 ValidateNotDisposed();
1347 return _stpStartInfo.MinWorkerThreads; 1347 return _stpStartInfo.MinWorkerThreads;
1348 } 1348 }
1349 set 1349 set
1350 { 1350 {
1351 Debug.Assert(value >= 0); 1351 Debug.Assert(value >= 0);
1352 Debug.Assert(value <= _stpStartInfo.MaxWorkerThreads); 1352 Debug.Assert(value <= _stpStartInfo.MaxWorkerThreads);
1353 if (_stpStartInfo.MaxWorkerThreads < value) 1353 if (_stpStartInfo.MaxWorkerThreads < value)
1354 { 1354 {
1355 _stpStartInfo.MaxWorkerThreads = value; 1355 _stpStartInfo.MaxWorkerThreads = value;
1356 } 1356 }
1357 _stpStartInfo.MinWorkerThreads = value; 1357 _stpStartInfo.MinWorkerThreads = value;
1358 StartOptimalNumberOfThreads(); 1358 StartOptimalNumberOfThreads();
1359 } 1359 }
1360 } 1360 }
1361 1361
1362 /// <summary> 1362 /// <summary>
1363 /// Get/Set the upper limit of threads in the pool. 1363 /// Get/Set the upper limit of threads in the pool.
1364 /// </summary> 1364 /// </summary>
1365 public int MaxThreads 1365 public int MaxThreads
1366 { 1366 {
1367 get 1367 get
1368 { 1368 {
1369 ValidateNotDisposed(); 1369 ValidateNotDisposed();
1370 return _stpStartInfo.MaxWorkerThreads; 1370 return _stpStartInfo.MaxWorkerThreads;
1371 } 1371 }
1372 1372
1373 set 1373 set
1374 { 1374 {
1375 Debug.Assert(value > 0); 1375 Debug.Assert(value > 0);
1376 Debug.Assert(value >= _stpStartInfo.MinWorkerThreads); 1376 Debug.Assert(value >= _stpStartInfo.MinWorkerThreads);
1377 if (_stpStartInfo.MinWorkerThreads > value) 1377 if (_stpStartInfo.MinWorkerThreads > value)
1378 { 1378 {
1379 _stpStartInfo.MinWorkerThreads = value; 1379 _stpStartInfo.MinWorkerThreads = value;
1380 } 1380 }
1381 _stpStartInfo.MaxWorkerThreads = value; 1381 _stpStartInfo.MaxWorkerThreads = value;
1382 StartOptimalNumberOfThreads(); 1382 StartOptimalNumberOfThreads();
1383 } 1383 }
1384 } 1384 }
1385 /// <summary> 1385 /// <summary>
1386 /// Get the number of threads in the thread pool. 1386 /// Get the number of threads in the thread pool.
1387 /// Should be between the lower and the upper limits. 1387 /// Should be between the lower and the upper limits.
1388 /// </summary> 1388 /// </summary>
1389 public int ActiveThreads 1389 public int ActiveThreads
1390 { 1390 {
1391 get 1391 get
1392 { 1392 {
1393 ValidateNotDisposed(); 1393 ValidateNotDisposed();
1394 return _workerThreads.Count; 1394 return _workerThreads.Count;
1395 } 1395 }
1396 } 1396 }
1397 1397
1398 /// <summary> 1398 /// <summary>
1399 /// Get the number of busy (not idle) threads in the thread pool. 1399 /// Get the number of busy (not idle) threads in the thread pool.
1400 /// </summary> 1400 /// </summary>
1401 public int InUseThreads 1401 public int InUseThreads
1402 { 1402 {
1403 get 1403 get
1404 { 1404 {
1405 ValidateNotDisposed(); 1405 ValidateNotDisposed();
1406 return _inUseWorkerThreads; 1406 return _inUseWorkerThreads;
1407 } 1407 }
1408 } 1408 }
1409 1409
1410 /// <summary> 1410 /// <summary>
1411 /// Returns true if the current running work item has been cancelled. 1411 /// Returns true if the current running work item has been cancelled.
1412 /// Must be used within the work item's callback method. 1412 /// Must be used within the work item's callback method.
1413 /// The work item should sample this value in order to know if it 1413 /// The work item should sample this value in order to know if it
1414 /// needs to quit before its completion. 1414 /// needs to quit before its completion.
1415 /// </summary> 1415 /// </summary>
1416 public static bool IsWorkItemCanceled 1416 public static bool IsWorkItemCanceled
1417 { 1417 {
1418 get 1418 get
1419 { 1419 {
1420 return CurrentThreadEntry.CurrentWorkItem.IsCanceled; 1420 return CurrentThreadEntry.CurrentWorkItem.IsCanceled;
1421 } 1421 }
1422 } 1422 }
1423 1423
1424 /// <summary> 1424 /// <summary>
1425 /// Checks if the work item has been cancelled, and if yes then abort the thread. 1425 /// Checks if the work item has been cancelled, and if yes then abort the thread.
1426 /// Can be used with Cancel and timeout 1426 /// Can be used with Cancel and timeout
1427 /// </summary> 1427 /// </summary>
1428 public static void AbortOnWorkItemCancel() 1428 public static void AbortOnWorkItemCancel()
1429 { 1429 {
1430 if (IsWorkItemCanceled) 1430 if (IsWorkItemCanceled)
1431 { 1431 {
1432 Thread.CurrentThread.Abort(); 1432 Thread.CurrentThread.Abort();
1433 } 1433 }
1434 } 1434 }
1435 1435
1436 /// <summary> 1436 /// <summary>
1437 /// Thread Pool start information (readonly) 1437 /// Thread Pool start information (readonly)
1438 /// </summary> 1438 /// </summary>
1439 public STPStartInfo STPStartInfo 1439 public STPStartInfo STPStartInfo
1440 { 1440 {
1441 get 1441 get
1442 { 1442 {
1443 return _stpStartInfo.AsReadOnly(); 1443 return _stpStartInfo.AsReadOnly();
1444 } 1444 }
1445 } 1445 }
1446 1446
1447 public bool IsShuttingdown 1447 public bool IsShuttingdown
1448 { 1448 {
1449 get { return _shutdown; } 1449 get { return _shutdown; }
1450 } 1450 }
1451 1451
1452 /// <summary> 1452 /// <summary>
1453 /// Return the local calculated performance counters 1453 /// Return the local calculated performance counters
1454 /// Available only if STPStartInfo.EnableLocalPerformanceCounters is true. 1454 /// Available only if STPStartInfo.EnableLocalPerformanceCounters is true.
1455 /// </summary> 1455 /// </summary>
1456 public ISTPPerformanceCountersReader PerformanceCountersReader 1456 public ISTPPerformanceCountersReader PerformanceCountersReader
1457 { 1457 {
1458 get { return (ISTPPerformanceCountersReader)_localPCs; } 1458 get { return (ISTPPerformanceCountersReader)_localPCs; }
1459 } 1459 }
1460 1460
1461 #endregion 1461 #endregion
1462 1462
1463 #region IDisposable Members 1463 #region IDisposable Members
1464 1464
1465 public void Dispose() 1465 public void Dispose()
1466 { 1466 {
1467 if (!_isDisposed) 1467 if (!_isDisposed)
1468 { 1468 {
1469 if (!_shutdown) 1469 if (!_shutdown)
1470 { 1470 {
1471 Shutdown(); 1471 Shutdown();
1472 } 1472 }
1473 1473
1474 if (null != _shuttingDownEvent) 1474 if (null != _shuttingDownEvent)
1475 { 1475 {
1476 _shuttingDownEvent.Close(); 1476 _shuttingDownEvent.Close();
1477 _shuttingDownEvent = null; 1477 _shuttingDownEvent = null;
1478 } 1478 }
1479 _workerThreads.Clear(); 1479 _workerThreads.Clear();
1480 1480
1481 if (null != _isIdleWaitHandle) 1481 if (null != _isIdleWaitHandle)
1482 { 1482 {
1483 _isIdleWaitHandle.Close(); 1483 _isIdleWaitHandle.Close();
1484 _isIdleWaitHandle = null; 1484 _isIdleWaitHandle = null;
1485 } 1485 }
1486 1486
1487 _isDisposed = true; 1487 _isDisposed = true;
1488 } 1488 }
1489 } 1489 }
1490 1490
1491 private void ValidateNotDisposed() 1491 private void ValidateNotDisposed()
1492 { 1492 {
1493 if(_isDisposed) 1493 if(_isDisposed)
1494 { 1494 {
1495 throw new ObjectDisposedException(GetType().ToString(), "The SmartThreadPool has been shutdown"); 1495 throw new ObjectDisposedException(GetType().ToString(), "The SmartThreadPool has been shutdown");
1496 } 1496 }
1497 } 1497 }
1498 #endregion 1498 #endregion
1499 1499
1500 #region WorkItemsGroupBase Overrides 1500 #region WorkItemsGroupBase Overrides
1501 1501
1502 /// <summary> 1502 /// <summary>
1503 /// Get/Set the maximum number of work items that execute cocurrency on the thread pool 1503 /// Get/Set the maximum number of work items that execute cocurrency on the thread pool
1504 /// </summary> 1504 /// </summary>
1505 public override int Concurrency 1505 public override int Concurrency
1506 { 1506 {
1507 get { return MaxThreads; } 1507 get { return MaxThreads; }
1508 set { MaxThreads = value; } 1508 set { MaxThreads = value; }
1509 } 1509 }
1510 1510
1511 /// <summary> 1511 /// <summary>
1512 /// Get the number of work items in the queue. 1512 /// Get the number of work items in the queue.
1513 /// </summary> 1513 /// </summary>
1514 public override int WaitingCallbacks 1514 public override int WaitingCallbacks
1515 { 1515 {
1516 get 1516 get
1517 { 1517 {
1518 ValidateNotDisposed(); 1518 ValidateNotDisposed();
1519 return _workItemsQueue.Count; 1519 return _workItemsQueue.Count;
1520 } 1520 }
1521 } 1521 }
1522 1522
1523 /// <summary> 1523 /// <summary>
1524 /// Get an array with all the state objects of the currently running items. 1524 /// Get an array with all the state objects of the currently running items.
1525 /// The array represents a snap shot and impact performance. 1525 /// The array represents a snap shot and impact performance.
1526 /// </summary> 1526 /// </summary>
1527 public override object[] GetStates() 1527 public override object[] GetStates()
1528 { 1528 {
1529 object[] states = _workItemsQueue.GetStates(); 1529 object[] states = _workItemsQueue.GetStates();
1530 return states; 1530 return states;
1531 } 1531 }
1532 1532
1533 /// <summary> 1533 /// <summary>
1534 /// WorkItemsGroup start information (readonly) 1534 /// WorkItemsGroup start information (readonly)
1535 /// </summary> 1535 /// </summary>
1536 public override WIGStartInfo WIGStartInfo 1536 public override WIGStartInfo WIGStartInfo
1537 { 1537 {
1538 get { return _stpStartInfo.AsReadOnly(); } 1538 get { return _stpStartInfo.AsReadOnly(); }
1539 } 1539 }
1540 1540
1541 /// <summary> 1541 /// <summary>
1542 /// Start the thread pool if it was started suspended. 1542 /// Start the thread pool if it was started suspended.
1543 /// If it is already running, this method is ignored. 1543 /// If it is already running, this method is ignored.
1544 /// </summary> 1544 /// </summary>
1545 public override void Start() 1545 public override void Start()
1546 { 1546 {
1547 if (!_isSuspended) 1547 if (!_isSuspended)
1548 { 1548 {
1549 return; 1549 return;
1550 } 1550 }
1551 _isSuspended = false; 1551 _isSuspended = false;
1552 1552
1553 ICollection workItemsGroups = _workItemsGroups.Values; 1553 ICollection workItemsGroups = _workItemsGroups.Values;
1554 foreach (WorkItemsGroup workItemsGroup in workItemsGroups) 1554 foreach (WorkItemsGroup workItemsGroup in workItemsGroups)
1555 { 1555 {
1556 workItemsGroup.OnSTPIsStarting(); 1556 workItemsGroup.OnSTPIsStarting();
1557 } 1557 }
1558 1558
1559 StartOptimalNumberOfThreads(); 1559 StartOptimalNumberOfThreads();
1560 } 1560 }
1561 1561
1562 /// <summary> 1562 /// <summary>
1563 /// Cancel all work items using thread abortion 1563 /// Cancel all work items using thread abortion
1564 /// </summary> 1564 /// </summary>
1565 /// <param name="abortExecution">True to stop work items by raising ThreadAbortException</param> 1565 /// <param name="abortExecution">True to stop work items by raising ThreadAbortException</param>
1566 public override void Cancel(bool abortExecution) 1566 public override void Cancel(bool abortExecution)
1567 { 1567 {
1568 _canceledSmartThreadPool.IsCanceled = true; 1568 _canceledSmartThreadPool.IsCanceled = true;
1569 _canceledSmartThreadPool = new CanceledWorkItemsGroup(); 1569 _canceledSmartThreadPool = new CanceledWorkItemsGroup();
1570 1570
1571 ICollection workItemsGroups = _workItemsGroups.Values; 1571 ICollection workItemsGroups = _workItemsGroups.Values;
1572 foreach (WorkItemsGroup workItemsGroup in workItemsGroups) 1572 foreach (WorkItemsGroup workItemsGroup in workItemsGroups)
1573 { 1573 {
1574 workItemsGroup.Cancel(abortExecution); 1574 workItemsGroup.Cancel(abortExecution);
1575 } 1575 }
1576 1576
1577 if (abortExecution) 1577 if (abortExecution)
1578 { 1578 {
1579 foreach (ThreadEntry threadEntry in _workerThreads.Values) 1579 foreach (ThreadEntry threadEntry in _workerThreads.Values)
1580 { 1580 {
1581 WorkItem workItem = threadEntry.CurrentWorkItem; 1581 WorkItem workItem = threadEntry.CurrentWorkItem;
1582 if (null != workItem && 1582 if (null != workItem &&
1583 threadEntry.AssociatedSmartThreadPool == this && 1583 threadEntry.AssociatedSmartThreadPool == this &&
1584 !workItem.IsCanceled) 1584 !workItem.IsCanceled)
1585 { 1585 {
1586 threadEntry.CurrentWorkItem.GetWorkItemResult().Cancel(true); 1586 threadEntry.CurrentWorkItem.GetWorkItemResult().Cancel(true);
1587 } 1587 }
1588 } 1588 }
1589 } 1589 }
1590 } 1590 }
1591 1591
1592 /// <summary> 1592 /// <summary>
1593 /// Wait for the thread pool to be idle 1593 /// Wait for the thread pool to be idle
1594 /// </summary> 1594 /// </summary>
1595 public override bool WaitForIdle(int millisecondsTimeout) 1595 public override bool WaitForIdle(int millisecondsTimeout)
1596 { 1596 {
1597 ValidateWaitForIdle(); 1597 ValidateWaitForIdle();
1598 return STPEventWaitHandle.WaitOne(_isIdleWaitHandle, millisecondsTimeout, false); 1598 return STPEventWaitHandle.WaitOne(_isIdleWaitHandle, millisecondsTimeout, false);
1599 } 1599 }
1600 1600
1601 /// <summary> 1601 /// <summary>
1602 /// This event is fired when all work items are completed. 1602 /// This event is fired when all work items are completed.
1603 /// (When IsIdle changes to true) 1603 /// (When IsIdle changes to true)
1604 /// This event only work on WorkItemsGroup. On SmartThreadPool 1604 /// This event only work on WorkItemsGroup. On SmartThreadPool
1605 /// it throws the NotImplementedException. 1605 /// it throws the NotImplementedException.
1606 /// </summary> 1606 /// </summary>
1607 public override event WorkItemsGroupIdleHandler OnIdle 1607 public override event WorkItemsGroupIdleHandler OnIdle
1608 { 1608 {
1609 add 1609 add
1610 { 1610 {
1611 throw new NotImplementedException("This event is not implemented in the SmartThreadPool class. Please create a WorkItemsGroup in order to use this feature."); 1611 throw new NotImplementedException("This event is not implemented in the SmartThreadPool class. Please create a WorkItemsGroup in order to use this feature.");
1612 //_onIdle += value; 1612 //_onIdle += value;
1613 } 1613 }
1614 remove 1614 remove
1615 { 1615 {
1616 throw new NotImplementedException("This event is not implemented in the SmartThreadPool class. Please create a WorkItemsGroup in order to use this feature."); 1616 throw new NotImplementedException("This event is not implemented in the SmartThreadPool class. Please create a WorkItemsGroup in order to use this feature.");
1617 //_onIdle -= value; 1617 //_onIdle -= value;
1618 } 1618 }
1619 } 1619 }
1620 1620
1621 internal override void PreQueueWorkItem() 1621 internal override void PreQueueWorkItem()
1622 { 1622 {
1623 ValidateNotDisposed(); 1623 ValidateNotDisposed();
1624 } 1624 }
1625 1625
1626 #endregion 1626 #endregion
1627 1627
1628 #region Join, Choice, Pipe, etc. 1628 #region Join, Choice, Pipe, etc.
1629 1629
1630 /// <summary> 1630 /// <summary>
1631 /// Executes all actions in parallel. 1631 /// Executes all actions in parallel.
1632 /// Returns when they all finish. 1632 /// Returns when they all finish.
1633 /// </summary> 1633 /// </summary>
1634 /// <param name="actions">Actions to execute</param> 1634 /// <param name="actions">Actions to execute</param>
1635 public void Join(IEnumerable<Action> actions) 1635 public void Join(IEnumerable<Action> actions)
1636 { 1636 {
1637 WIGStartInfo wigStartInfo = new WIGStartInfo { StartSuspended = true }; 1637 WIGStartInfo wigStartInfo = new WIGStartInfo { StartSuspended = true };
1638 IWorkItemsGroup workItemsGroup = CreateWorkItemsGroup(int.MaxValue, wigStartInfo); 1638 IWorkItemsGroup workItemsGroup = CreateWorkItemsGroup(int.MaxValue, wigStartInfo);
1639 foreach (Action action in actions) 1639 foreach (Action action in actions)
1640 { 1640 {
1641 workItemsGroup.QueueWorkItem(action); 1641 workItemsGroup.QueueWorkItem(action);
1642 } 1642 }
1643 workItemsGroup.Start(); 1643 workItemsGroup.Start();
1644 workItemsGroup.WaitForIdle(); 1644 workItemsGroup.WaitForIdle();
1645 } 1645 }
1646 1646
1647 /// <summary> 1647 /// <summary>
1648 /// Executes all actions in parallel. 1648 /// Executes all actions in parallel.
1649 /// Returns when they all finish. 1649 /// Returns when they all finish.
1650 /// </summary> 1650 /// </summary>
1651 /// <param name="actions">Actions to execute</param> 1651 /// <param name="actions">Actions to execute</param>
1652 public void Join(params Action[] actions) 1652 public void Join(params Action[] actions)
1653 { 1653 {
1654 Join((IEnumerable<Action>)actions); 1654 Join((IEnumerable<Action>)actions);
1655 } 1655 }
1656 1656
1657 private class ChoiceIndex 1657 private class ChoiceIndex
1658 { 1658 {
1659 public int _index = -1; 1659 public int _index = -1;
1660 } 1660 }
1661 1661
1662 /// <summary> 1662 /// <summary>
1663 /// Executes all actions in parallel 1663 /// Executes all actions in parallel
1664 /// Returns when the first one completes 1664 /// Returns when the first one completes
1665 /// </summary> 1665 /// </summary>
1666 /// <param name="actions">Actions to execute</param> 1666 /// <param name="actions">Actions to execute</param>
1667 public int Choice(IEnumerable<Action> actions) 1667 public int Choice(IEnumerable<Action> actions)
1668 { 1668 {
1669 WIGStartInfo wigStartInfo = new WIGStartInfo { StartSuspended = true }; 1669 WIGStartInfo wigStartInfo = new WIGStartInfo { StartSuspended = true };
1670 IWorkItemsGroup workItemsGroup = CreateWorkItemsGroup(int.MaxValue, wigStartInfo); 1670 IWorkItemsGroup workItemsGroup = CreateWorkItemsGroup(int.MaxValue, wigStartInfo);
1671 1671
1672 ManualResetEvent anActionCompleted = new ManualResetEvent(false); 1672 ManualResetEvent anActionCompleted = new ManualResetEvent(false);
1673 1673
1674 ChoiceIndex choiceIndex = new ChoiceIndex(); 1674 ChoiceIndex choiceIndex = new ChoiceIndex();
1675 1675
1676 int i = 0; 1676 int i = 0;
1677 foreach (Action action in actions) 1677 foreach (Action action in actions)
1678 { 1678 {
1679 Action act = action; 1679 Action act = action;
1680 int value = i; 1680 int value = i;
1681 workItemsGroup.QueueWorkItem(() => { act(); Interlocked.CompareExchange(ref choiceIndex._index, value, -1); anActionCompleted.Set(); }); 1681 workItemsGroup.QueueWorkItem(() => { act(); Interlocked.CompareExchange(ref choiceIndex._index, value, -1); anActionCompleted.Set(); });
1682 ++i; 1682 ++i;
1683 } 1683 }
1684 workItemsGroup.Start(); 1684 workItemsGroup.Start();
1685 anActionCompleted.WaitOne(); 1685 anActionCompleted.WaitOne();
1686 1686
1687 return choiceIndex._index; 1687 return choiceIndex._index;
1688 } 1688 }
1689 1689
1690 /// <summary> 1690 /// <summary>
1691 /// Executes all actions in parallel 1691 /// Executes all actions in parallel
1692 /// Returns when the first one completes 1692 /// Returns when the first one completes
1693 /// </summary> 1693 /// </summary>
1694 /// <param name="actions">Actions to execute</param> 1694 /// <param name="actions">Actions to execute</param>
1695 public int Choice(params Action[] actions) 1695 public int Choice(params Action[] actions)
1696 { 1696 {
1697 return Choice((IEnumerable<Action>)actions); 1697 return Choice((IEnumerable<Action>)actions);
1698 } 1698 }
1699 1699
1700 /// <summary> 1700 /// <summary>
1701 /// Executes actions in sequence asynchronously. 1701 /// Executes actions in sequence asynchronously.
1702 /// Returns immediately. 1702 /// Returns immediately.
1703 /// </summary> 1703 /// </summary>
1704 /// <param name="pipeState">A state context that passes </param> 1704 /// <param name="pipeState">A state context that passes </param>
1705 /// <param name="actions">Actions to execute in the order they should run</param> 1705 /// <param name="actions">Actions to execute in the order they should run</param>
1706 public void Pipe<T>(T pipeState, IEnumerable<Action<T>> actions) 1706 public void Pipe<T>(T pipeState, IEnumerable<Action<T>> actions)
1707 { 1707 {
1708 WIGStartInfo wigStartInfo = new WIGStartInfo { StartSuspended = true }; 1708 WIGStartInfo wigStartInfo = new WIGStartInfo { StartSuspended = true };
1709 IWorkItemsGroup workItemsGroup = CreateWorkItemsGroup(1, wigStartInfo); 1709 IWorkItemsGroup workItemsGroup = CreateWorkItemsGroup(1, wigStartInfo);
1710 foreach (Action<T> action in actions) 1710 foreach (Action<T> action in actions)
1711 { 1711 {
1712 Action<T> act = action; 1712 Action<T> act = action;
1713 workItemsGroup.QueueWorkItem(() => act(pipeState)); 1713 workItemsGroup.QueueWorkItem(() => act(pipeState));
1714 } 1714 }
1715 workItemsGroup.Start(); 1715 workItemsGroup.Start();
1716 workItemsGroup.WaitForIdle(); 1716 workItemsGroup.WaitForIdle();
1717 } 1717 }
1718 1718
1719 /// <summary> 1719 /// <summary>
1720 /// Executes actions in sequence asynchronously. 1720 /// Executes actions in sequence asynchronously.
1721 /// Returns immediately. 1721 /// Returns immediately.
1722 /// </summary> 1722 /// </summary>
1723 /// <param name="pipeState"></param> 1723 /// <param name="pipeState"></param>
1724 /// <param name="actions">Actions to execute in the order they should run</param> 1724 /// <param name="actions">Actions to execute in the order they should run</param>
1725 public void Pipe<T>(T pipeState, params Action<T>[] actions) 1725 public void Pipe<T>(T pipeState, params Action<T>[] actions)
1726 { 1726 {
1727 Pipe(pipeState, (IEnumerable<Action<T>>)actions); 1727 Pipe(pipeState, (IEnumerable<Action<T>>)actions);
1728 } 1728 }
1729 #endregion 1729 #endregion
1730 } 1730 }
1731 #endregion 1731 #endregion
1732} 1732}
diff --git a/ThirdParty/SmartThreadPool/SynchronizedDictionary.cs b/ThirdParty/SmartThreadPool/SynchronizedDictionary.cs
index 3532cca..0cce19f 100644
--- a/ThirdParty/SmartThreadPool/SynchronizedDictionary.cs
+++ b/ThirdParty/SmartThreadPool/SynchronizedDictionary.cs
@@ -1,89 +1,89 @@
1using System.Collections.Generic; 1using System.Collections.Generic;
2 2
3namespace Amib.Threading.Internal 3namespace Amib.Threading.Internal
4{ 4{
5 internal class SynchronizedDictionary<TKey, TValue> 5 internal class SynchronizedDictionary<TKey, TValue>
6 { 6 {
7 private readonly Dictionary<TKey, TValue> _dictionary; 7 private readonly Dictionary<TKey, TValue> _dictionary;
8 private readonly object _lock; 8 private readonly object _lock;
9 9
10 public SynchronizedDictionary() 10 public SynchronizedDictionary()
11 { 11 {
12 _lock = new object(); 12 _lock = new object();
13 _dictionary = new Dictionary<TKey, TValue>(); 13 _dictionary = new Dictionary<TKey, TValue>();
14 } 14 }
15 15
16 public int Count 16 public int Count
17 { 17 {
18 get { return _dictionary.Count; } 18 get { return _dictionary.Count; }
19 } 19 }
20 20
21 public bool Contains(TKey key) 21 public bool Contains(TKey key)
22 { 22 {
23 lock (_lock) 23 lock (_lock)
24 { 24 {
25 return _dictionary.ContainsKey(key); 25 return _dictionary.ContainsKey(key);
26 } 26 }
27 } 27 }
28 28
29 public void Remove(TKey key) 29 public void Remove(TKey key)
30 { 30 {
31 lock (_lock) 31 lock (_lock)
32 { 32 {
33 _dictionary.Remove(key); 33 _dictionary.Remove(key);
34 } 34 }
35 } 35 }
36 36
37 public object SyncRoot 37 public object SyncRoot
38 { 38 {
39 get { return _lock; } 39 get { return _lock; }
40 } 40 }
41 41
42 public TValue this[TKey key] 42 public TValue this[TKey key]
43 { 43 {
44 get 44 get
45 { 45 {
46 lock (_lock) 46 lock (_lock)
47 { 47 {
48 return _dictionary[key]; 48 return _dictionary[key];
49 } 49 }
50 } 50 }
51 set 51 set
52 { 52 {
53 lock (_lock) 53 lock (_lock)
54 { 54 {
55 _dictionary[key] = value; 55 _dictionary[key] = value;
56 } 56 }
57 } 57 }
58 } 58 }
59 59
60 public Dictionary<TKey, TValue>.KeyCollection Keys 60 public Dictionary<TKey, TValue>.KeyCollection Keys
61 { 61 {
62 get 62 get
63 { 63 {
64 lock (_lock) 64 lock (_lock)
65 { 65 {
66 return _dictionary.Keys; 66 return _dictionary.Keys;
67 } 67 }
68 } 68 }
69 } 69 }
70 70
71 public Dictionary<TKey, TValue>.ValueCollection Values 71 public Dictionary<TKey, TValue>.ValueCollection Values
72 { 72 {
73 get 73 get
74 { 74 {
75 lock (_lock) 75 lock (_lock)
76 { 76 {
77 return _dictionary.Values; 77 return _dictionary.Values;
78 } 78 }
79 } 79 }
80 } 80 }
81 public void Clear() 81 public void Clear()
82 { 82 {
83 lock (_lock) 83 lock (_lock)
84 { 84 {
85 _dictionary.Clear(); 85 _dictionary.Clear();
86 } 86 }
87 } 87 }
88 } 88 }
89} 89}
diff --git a/ThirdParty/SmartThreadPool/WIGStartInfo.cs b/ThirdParty/SmartThreadPool/WIGStartInfo.cs
index e5ff150..8af195b 100644
--- a/ThirdParty/SmartThreadPool/WIGStartInfo.cs
+++ b/ThirdParty/SmartThreadPool/WIGStartInfo.cs
@@ -1,171 +1,171 @@
1using System; 1using System;
2 2
3namespace Amib.Threading 3namespace Amib.Threading
4{ 4{
5 /// <summary> 5 /// <summary>
6 /// Summary description for WIGStartInfo. 6 /// Summary description for WIGStartInfo.
7 /// </summary> 7 /// </summary>
8 public class WIGStartInfo 8 public class WIGStartInfo
9 { 9 {
10 private bool _useCallerCallContext; 10 private bool _useCallerCallContext;
11 private bool _useCallerHttpContext; 11 private bool _useCallerHttpContext;
12 private bool _disposeOfStateObjects; 12 private bool _disposeOfStateObjects;
13 private CallToPostExecute _callToPostExecute; 13 private CallToPostExecute _callToPostExecute;
14 private PostExecuteWorkItemCallback _postExecuteWorkItemCallback; 14 private PostExecuteWorkItemCallback _postExecuteWorkItemCallback;
15 private bool _startSuspended; 15 private bool _startSuspended;
16 private WorkItemPriority _workItemPriority; 16 private WorkItemPriority _workItemPriority;
17 private bool _fillStateWithArgs; 17 private bool _fillStateWithArgs;
18 18
19 protected bool _readOnly; 19 protected bool _readOnly;
20 20
21 public WIGStartInfo() 21 public WIGStartInfo()
22 { 22 {
23 _fillStateWithArgs = SmartThreadPool.DefaultFillStateWithArgs; 23 _fillStateWithArgs = SmartThreadPool.DefaultFillStateWithArgs;
24 _workItemPriority = SmartThreadPool.DefaultWorkItemPriority; 24 _workItemPriority = SmartThreadPool.DefaultWorkItemPriority;
25 _startSuspended = SmartThreadPool.DefaultStartSuspended; 25 _startSuspended = SmartThreadPool.DefaultStartSuspended;
26 _postExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback; 26 _postExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback;
27 _callToPostExecute = SmartThreadPool.DefaultCallToPostExecute; 27 _callToPostExecute = SmartThreadPool.DefaultCallToPostExecute;
28 _disposeOfStateObjects = SmartThreadPool.DefaultDisposeOfStateObjects; 28 _disposeOfStateObjects = SmartThreadPool.DefaultDisposeOfStateObjects;
29 _useCallerHttpContext = SmartThreadPool.DefaultUseCallerHttpContext; 29 _useCallerHttpContext = SmartThreadPool.DefaultUseCallerHttpContext;
30 _useCallerCallContext = SmartThreadPool.DefaultUseCallerCallContext; 30 _useCallerCallContext = SmartThreadPool.DefaultUseCallerCallContext;
31 } 31 }
32 32
33 public WIGStartInfo(WIGStartInfo wigStartInfo) 33 public WIGStartInfo(WIGStartInfo wigStartInfo)
34 { 34 {
35 _useCallerCallContext = wigStartInfo.UseCallerCallContext; 35 _useCallerCallContext = wigStartInfo.UseCallerCallContext;
36 _useCallerHttpContext = wigStartInfo.UseCallerHttpContext; 36 _useCallerHttpContext = wigStartInfo.UseCallerHttpContext;
37 _disposeOfStateObjects = wigStartInfo.DisposeOfStateObjects; 37 _disposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
38 _callToPostExecute = wigStartInfo.CallToPostExecute; 38 _callToPostExecute = wigStartInfo.CallToPostExecute;
39 _postExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback; 39 _postExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback;
40 _workItemPriority = wigStartInfo.WorkItemPriority; 40 _workItemPriority = wigStartInfo.WorkItemPriority;
41 _startSuspended = wigStartInfo.StartSuspended; 41 _startSuspended = wigStartInfo.StartSuspended;
42 _fillStateWithArgs = wigStartInfo.FillStateWithArgs; 42 _fillStateWithArgs = wigStartInfo.FillStateWithArgs;
43 } 43 }
44 44
45 protected void ThrowIfReadOnly() 45 protected void ThrowIfReadOnly()
46 { 46 {
47 if (_readOnly) 47 if (_readOnly)
48 { 48 {
49 throw new NotSupportedException("This is a readonly instance and set is not supported"); 49 throw new NotSupportedException("This is a readonly instance and set is not supported");
50 } 50 }
51 } 51 }
52 52
53 /// <summary> 53 /// <summary>
54 /// Get/Set if to use the caller's security context 54 /// Get/Set if to use the caller's security context
55 /// </summary> 55 /// </summary>
56 public virtual bool UseCallerCallContext 56 public virtual bool UseCallerCallContext
57 { 57 {
58 get { return _useCallerCallContext; } 58 get { return _useCallerCallContext; }
59 set 59 set
60 { 60 {
61 ThrowIfReadOnly(); 61 ThrowIfReadOnly();
62 _useCallerCallContext = value; 62 _useCallerCallContext = value;
63 } 63 }
64 } 64 }
65 65
66 66
67 /// <summary> 67 /// <summary>
68 /// Get/Set if to use the caller's HTTP context 68 /// Get/Set if to use the caller's HTTP context
69 /// </summary> 69 /// </summary>
70 public virtual bool UseCallerHttpContext 70 public virtual bool UseCallerHttpContext
71 { 71 {
72 get { return _useCallerHttpContext; } 72 get { return _useCallerHttpContext; }
73 set 73 set
74 { 74 {
75 ThrowIfReadOnly(); 75 ThrowIfReadOnly();
76 _useCallerHttpContext = value; 76 _useCallerHttpContext = value;
77 } 77 }
78 } 78 }
79 79
80 80
81 /// <summary> 81 /// <summary>
82 /// Get/Set if to dispose of the state object of a work item 82 /// Get/Set if to dispose of the state object of a work item
83 /// </summary> 83 /// </summary>
84 public virtual bool DisposeOfStateObjects 84 public virtual bool DisposeOfStateObjects
85 { 85 {
86 get { return _disposeOfStateObjects; } 86 get { return _disposeOfStateObjects; }
87 set 87 set
88 { 88 {
89 ThrowIfReadOnly(); 89 ThrowIfReadOnly();
90 _disposeOfStateObjects = value; 90 _disposeOfStateObjects = value;
91 } 91 }
92 } 92 }
93 93
94 94
95 /// <summary> 95 /// <summary>
96 /// Get/Set the run the post execute options 96 /// Get/Set the run the post execute options
97 /// </summary> 97 /// </summary>
98 public virtual CallToPostExecute CallToPostExecute 98 public virtual CallToPostExecute CallToPostExecute
99 { 99 {
100 get { return _callToPostExecute; } 100 get { return _callToPostExecute; }
101 set 101 set
102 { 102 {
103 ThrowIfReadOnly(); 103 ThrowIfReadOnly();
104 _callToPostExecute = value; 104 _callToPostExecute = value;
105 } 105 }
106 } 106 }
107 107
108 108
109 /// <summary> 109 /// <summary>
110 /// Get/Set the default post execute callback 110 /// Get/Set the default post execute callback
111 /// </summary> 111 /// </summary>
112 public virtual PostExecuteWorkItemCallback PostExecuteWorkItemCallback 112 public virtual PostExecuteWorkItemCallback PostExecuteWorkItemCallback
113 { 113 {
114 get { return _postExecuteWorkItemCallback; } 114 get { return _postExecuteWorkItemCallback; }
115 set 115 set
116 { 116 {
117 ThrowIfReadOnly(); 117 ThrowIfReadOnly();
118 _postExecuteWorkItemCallback = value; 118 _postExecuteWorkItemCallback = value;
119 } 119 }
120 } 120 }
121 121
122 122
123 /// <summary> 123 /// <summary>
124 /// Get/Set if the work items execution should be suspended until the Start() 124 /// Get/Set if the work items execution should be suspended until the Start()
125 /// method is called. 125 /// method is called.
126 /// </summary> 126 /// </summary>
127 public virtual bool StartSuspended 127 public virtual bool StartSuspended
128 { 128 {
129 get { return _startSuspended; } 129 get { return _startSuspended; }
130 set 130 set
131 { 131 {
132 ThrowIfReadOnly(); 132 ThrowIfReadOnly();
133 _startSuspended = value; 133 _startSuspended = value;
134 } 134 }
135 } 135 }
136 136
137 137
138 /// <summary> 138 /// <summary>
139 /// Get/Set the default priority that a work item gets when it is enqueued 139 /// Get/Set the default priority that a work item gets when it is enqueued
140 /// </summary> 140 /// </summary>
141 public virtual WorkItemPriority WorkItemPriority 141 public virtual WorkItemPriority WorkItemPriority
142 { 142 {
143 get { return _workItemPriority; } 143 get { return _workItemPriority; }
144 set { _workItemPriority = value; } 144 set { _workItemPriority = value; }
145 } 145 }
146 146
147 /// <summary> 147 /// <summary>
148 /// Get/Set the if QueueWorkItem of Action&lt;...&gt;/Func&lt;...&gt; fill the 148 /// Get/Set the if QueueWorkItem of Action&lt;...&gt;/Func&lt;...&gt; fill the
149 /// arguments as an object array into the state of the work item. 149 /// arguments as an object array into the state of the work item.
150 /// The arguments can be access later by IWorkItemResult.State. 150 /// The arguments can be access later by IWorkItemResult.State.
151 /// </summary> 151 /// </summary>
152 public virtual bool FillStateWithArgs 152 public virtual bool FillStateWithArgs
153 { 153 {
154 get { return _fillStateWithArgs; } 154 get { return _fillStateWithArgs; }
155 set 155 set
156 { 156 {
157 ThrowIfReadOnly(); 157 ThrowIfReadOnly();
158 _fillStateWithArgs = value; 158 _fillStateWithArgs = value;
159 } 159 }
160 } 160 }
161 161
162 /// <summary> 162 /// <summary>
163 /// Get a readonly version of this WIGStartInfo 163 /// Get a readonly version of this WIGStartInfo
164 /// </summary> 164 /// </summary>
165 /// <returns>Returns a readonly reference to this WIGStartInfoRO</returns> 165 /// <returns>Returns a readonly reference to this WIGStartInfoRO</returns>
166 public WIGStartInfo AsReadOnly() 166 public WIGStartInfo AsReadOnly()
167 { 167 {
168 return new WIGStartInfo(this) { _readOnly = true }; 168 return new WIGStartInfo(this) { _readOnly = true };
169 } 169 }
170 } 170 }
171} 171}
diff --git a/ThirdParty/SmartThreadPool/WorkItem.WorkItemResult.cs b/ThirdParty/SmartThreadPool/WorkItem.WorkItemResult.cs
index 5745c15..435a14b 100644
--- a/ThirdParty/SmartThreadPool/WorkItem.WorkItemResult.cs
+++ b/ThirdParty/SmartThreadPool/WorkItem.WorkItemResult.cs
@@ -1,190 +1,190 @@
1using System; 1using System;
2using System.Collections.Generic; 2using System.Collections.Generic;
3using System.Text; 3using System.Text;
4using System.Threading; 4using System.Threading;
5 5
6namespace Amib.Threading.Internal 6namespace Amib.Threading.Internal
7{ 7{
8 public partial class WorkItem 8 public partial class WorkItem
9 { 9 {
10 #region WorkItemResult class 10 #region WorkItemResult class
11 11
12 private class WorkItemResult : IWorkItemResult, IInternalWorkItemResult, IInternalWaitableResult 12 private class WorkItemResult : IWorkItemResult, IInternalWorkItemResult, IInternalWaitableResult
13 { 13 {
14 /// <summary> 14 /// <summary>
15 /// A back reference to the work item 15 /// A back reference to the work item
16 /// </summary> 16 /// </summary>
17 private readonly WorkItem _workItem; 17 private readonly WorkItem _workItem;
18 18
19 public WorkItemResult(WorkItem workItem) 19 public WorkItemResult(WorkItem workItem)
20 { 20 {
21 _workItem = workItem; 21 _workItem = workItem;
22 } 22 }
23 23
24 internal WorkItem GetWorkItem() 24 internal WorkItem GetWorkItem()
25 { 25 {
26 return _workItem; 26 return _workItem;
27 } 27 }
28 28
29 #region IWorkItemResult Members 29 #region IWorkItemResult Members
30 30
31 public bool IsCompleted 31 public bool IsCompleted
32 { 32 {
33 get 33 get
34 { 34 {
35 return _workItem.IsCompleted; 35 return _workItem.IsCompleted;
36 } 36 }
37 } 37 }
38 38
39 public bool IsCanceled 39 public bool IsCanceled
40 { 40 {
41 get 41 get
42 { 42 {
43 return _workItem.IsCanceled; 43 return _workItem.IsCanceled;
44 } 44 }
45 } 45 }
46 46
47 public object GetResult() 47 public object GetResult()
48 { 48 {
49 return _workItem.GetResult(Timeout.Infinite, true, null); 49 return _workItem.GetResult(Timeout.Infinite, true, null);
50 } 50 }
51 51
52 public object GetResult(int millisecondsTimeout, bool exitContext) 52 public object GetResult(int millisecondsTimeout, bool exitContext)
53 { 53 {
54 return _workItem.GetResult(millisecondsTimeout, exitContext, null); 54 return _workItem.GetResult(millisecondsTimeout, exitContext, null);
55 } 55 }
56 56
57 public object GetResult(TimeSpan timeout, bool exitContext) 57 public object GetResult(TimeSpan timeout, bool exitContext)
58 { 58 {
59 return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null); 59 return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null);
60 } 60 }
61 61
62 public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle) 62 public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle)
63 { 63 {
64 return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle); 64 return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle);
65 } 65 }
66 66
67 public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle) 67 public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle)
68 { 68 {
69 return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle); 69 return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle);
70 } 70 }
71 71
72 public object GetResult(out Exception e) 72 public object GetResult(out Exception e)
73 { 73 {
74 return _workItem.GetResult(Timeout.Infinite, true, null, out e); 74 return _workItem.GetResult(Timeout.Infinite, true, null, out e);
75 } 75 }
76 76
77 public object GetResult(int millisecondsTimeout, bool exitContext, out Exception e) 77 public object GetResult(int millisecondsTimeout, bool exitContext, out Exception e)
78 { 78 {
79 return _workItem.GetResult(millisecondsTimeout, exitContext, null, out e); 79 return _workItem.GetResult(millisecondsTimeout, exitContext, null, out e);
80 } 80 }
81 81
82 public object GetResult(TimeSpan timeout, bool exitContext, out Exception e) 82 public object GetResult(TimeSpan timeout, bool exitContext, out Exception e)
83 { 83 {
84 return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null, out e); 84 return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null, out e);
85 } 85 }
86 86
87 public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e) 87 public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
88 { 88 {
89 return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e); 89 return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e);
90 } 90 }
91 91
92 public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e) 92 public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
93 { 93 {
94 return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle, out e); 94 return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle, out e);
95 } 95 }
96 96
97 public bool Cancel() 97 public bool Cancel()
98 { 98 {
99 return Cancel(false); 99 return Cancel(false);
100 } 100 }
101 101
102 public bool Cancel(bool abortExecution) 102 public bool Cancel(bool abortExecution)
103 { 103 {
104 return _workItem.Cancel(abortExecution); 104 return _workItem.Cancel(abortExecution);
105 } 105 }
106 106
107 public object State 107 public object State
108 { 108 {
109 get 109 get
110 { 110 {
111 return _workItem._state; 111 return _workItem._state;
112 } 112 }
113 } 113 }
114 114
115 public WorkItemPriority WorkItemPriority 115 public WorkItemPriority WorkItemPriority
116 { 116 {
117 get 117 get
118 { 118 {
119 return _workItem._workItemInfo.WorkItemPriority; 119 return _workItem._workItemInfo.WorkItemPriority;
120 } 120 }
121 } 121 }
122 122
123 /// <summary> 123 /// <summary>
124 /// Return the result, same as GetResult() 124 /// Return the result, same as GetResult()
125 /// </summary> 125 /// </summary>
126 public object Result 126 public object Result
127 { 127 {
128 get { return GetResult(); } 128 get { return GetResult(); }
129 } 129 }
130 130
131 /// <summary> 131 /// <summary>
132 /// Returns the exception if occured otherwise returns null. 132 /// Returns the exception if occured otherwise returns null.
133 /// This value is valid only after the work item completed, 133 /// This value is valid only after the work item completed,
134 /// before that it is always null. 134 /// before that it is always null.
135 /// </summary> 135 /// </summary>
136 public object Exception 136 public object Exception
137 { 137 {
138 get { return _workItem._exception; } 138 get { return _workItem._exception; }
139 } 139 }
140 140
141 #endregion 141 #endregion
142 142
143 #region IInternalWorkItemResult Members 143 #region IInternalWorkItemResult Members
144 144
145 public event WorkItemStateCallback OnWorkItemStarted 145 public event WorkItemStateCallback OnWorkItemStarted
146 { 146 {
147 add 147 add
148 { 148 {
149 _workItem.OnWorkItemStarted += value; 149 _workItem.OnWorkItemStarted += value;
150 } 150 }
151 remove 151 remove
152 { 152 {
153 _workItem.OnWorkItemStarted -= value; 153 _workItem.OnWorkItemStarted -= value;
154 } 154 }
155 } 155 }
156 156
157 157
158 public event WorkItemStateCallback OnWorkItemCompleted 158 public event WorkItemStateCallback OnWorkItemCompleted
159 { 159 {
160 add 160 add
161 { 161 {
162 _workItem.OnWorkItemCompleted += value; 162 _workItem.OnWorkItemCompleted += value;
163 } 163 }
164 remove 164 remove
165 { 165 {
166 _workItem.OnWorkItemCompleted -= value; 166 _workItem.OnWorkItemCompleted -= value;
167 } 167 }
168 } 168 }
169 169
170 #endregion 170 #endregion
171 171
172 #region IInternalWorkItemResult Members 172 #region IInternalWorkItemResult Members
173 173
174 public IWorkItemResult GetWorkItemResult() 174 public IWorkItemResult GetWorkItemResult()
175 { 175 {
176 return this; 176 return this;
177 } 177 }
178 178
179 public IWorkItemResult<TResult> GetWorkItemResultT<TResult>() 179 public IWorkItemResult<TResult> GetWorkItemResultT<TResult>()
180 { 180 {
181 return new WorkItemResultTWrapper<TResult>(this); 181 return new WorkItemResultTWrapper<TResult>(this);
182 } 182 }
183 183
184 #endregion 184 #endregion
185 } 185 }
186 186
187 #endregion 187 #endregion
188 188
189 } 189 }
190} 190}
diff --git a/ThirdParty/SmartThreadPool/WorkItemFactory.cs b/ThirdParty/SmartThreadPool/WorkItemFactory.cs
index 2d6601e..16ccd81 100644
--- a/ThirdParty/SmartThreadPool/WorkItemFactory.cs
+++ b/ThirdParty/SmartThreadPool/WorkItemFactory.cs
@@ -1,343 +1,343 @@
1using System; 1using System;
2 2
3namespace Amib.Threading.Internal 3namespace Amib.Threading.Internal
4{ 4{
5 #region WorkItemFactory class 5 #region WorkItemFactory class
6 6
7 public class WorkItemFactory 7 public class WorkItemFactory
8 { 8 {
9 /// <summary> 9 /// <summary>
10 /// Create a new work item 10 /// Create a new work item
11 /// </summary> 11 /// </summary>
12 /// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param> 12 /// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
13 /// <param name="wigStartInfo">Work item group start information</param> 13 /// <param name="wigStartInfo">Work item group start information</param>
14 /// <param name="callback">A callback to execute</param> 14 /// <param name="callback">A callback to execute</param>
15 /// <returns>Returns a work item</returns> 15 /// <returns>Returns a work item</returns>
16 public static WorkItem CreateWorkItem( 16 public static WorkItem CreateWorkItem(
17 IWorkItemsGroup workItemsGroup, 17 IWorkItemsGroup workItemsGroup,
18 WIGStartInfo wigStartInfo, 18 WIGStartInfo wigStartInfo,
19 WorkItemCallback callback) 19 WorkItemCallback callback)
20 { 20 {
21 return CreateWorkItem(workItemsGroup, wigStartInfo, callback, null); 21 return CreateWorkItem(workItemsGroup, wigStartInfo, callback, null);
22 } 22 }
23 23
24 /// <summary> 24 /// <summary>
25 /// Create a new work item 25 /// Create a new work item
26 /// </summary> 26 /// </summary>
27 /// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param> 27 /// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
28 /// <param name="wigStartInfo">Work item group start information</param> 28 /// <param name="wigStartInfo">Work item group start information</param>
29 /// <param name="callback">A callback to execute</param> 29 /// <param name="callback">A callback to execute</param>
30 /// <param name="workItemPriority">The priority of the work item</param> 30 /// <param name="workItemPriority">The priority of the work item</param>
31 /// <returns>Returns a work item</returns> 31 /// <returns>Returns a work item</returns>
32 public static WorkItem CreateWorkItem( 32 public static WorkItem CreateWorkItem(
33 IWorkItemsGroup workItemsGroup, 33 IWorkItemsGroup workItemsGroup,
34 WIGStartInfo wigStartInfo, 34 WIGStartInfo wigStartInfo,
35 WorkItemCallback callback, 35 WorkItemCallback callback,
36 WorkItemPriority workItemPriority) 36 WorkItemPriority workItemPriority)
37 { 37 {
38 return CreateWorkItem(workItemsGroup, wigStartInfo, callback, null, workItemPriority); 38 return CreateWorkItem(workItemsGroup, wigStartInfo, callback, null, workItemPriority);
39 } 39 }
40 40
41 /// <summary> 41 /// <summary>
42 /// Create a new work item 42 /// Create a new work item
43 /// </summary> 43 /// </summary>
44 /// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param> 44 /// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
45 /// <param name="wigStartInfo">Work item group start information</param> 45 /// <param name="wigStartInfo">Work item group start information</param>
46 /// <param name="workItemInfo">Work item info</param> 46 /// <param name="workItemInfo">Work item info</param>
47 /// <param name="callback">A callback to execute</param> 47 /// <param name="callback">A callback to execute</param>
48 /// <returns>Returns a work item</returns> 48 /// <returns>Returns a work item</returns>
49 public static WorkItem CreateWorkItem( 49 public static WorkItem CreateWorkItem(
50 IWorkItemsGroup workItemsGroup, 50 IWorkItemsGroup workItemsGroup,
51 WIGStartInfo wigStartInfo, 51 WIGStartInfo wigStartInfo,
52 WorkItemInfo workItemInfo, 52 WorkItemInfo workItemInfo,
53 WorkItemCallback callback) 53 WorkItemCallback callback)
54 { 54 {
55 return CreateWorkItem( 55 return CreateWorkItem(
56 workItemsGroup, 56 workItemsGroup,
57 wigStartInfo, 57 wigStartInfo,
58 workItemInfo, 58 workItemInfo,
59 callback, 59 callback,
60 null); 60 null);
61 } 61 }
62 62
63 /// <summary> 63 /// <summary>
64 /// Create a new work item 64 /// Create a new work item
65 /// </summary> 65 /// </summary>
66 /// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param> 66 /// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
67 /// <param name="wigStartInfo">Work item group start information</param> 67 /// <param name="wigStartInfo">Work item group start information</param>
68 /// <param name="callback">A callback to execute</param> 68 /// <param name="callback">A callback to execute</param>
69 /// <param name="state"> 69 /// <param name="state">
70 /// The context object of the work item. Used for passing arguments to the work item. 70 /// The context object of the work item. Used for passing arguments to the work item.
71 /// </param> 71 /// </param>
72 /// <returns>Returns a work item</returns> 72 /// <returns>Returns a work item</returns>
73 public static WorkItem CreateWorkItem( 73 public static WorkItem CreateWorkItem(
74 IWorkItemsGroup workItemsGroup, 74 IWorkItemsGroup workItemsGroup,
75 WIGStartInfo wigStartInfo, 75 WIGStartInfo wigStartInfo,
76 WorkItemCallback callback, 76 WorkItemCallback callback,
77 object state) 77 object state)
78 { 78 {
79 ValidateCallback(callback); 79 ValidateCallback(callback);
80 80
81 WorkItemInfo workItemInfo = new WorkItemInfo(); 81 WorkItemInfo workItemInfo = new WorkItemInfo();
82 workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext; 82 workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
83 workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext; 83 workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
84 workItemInfo.PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback; 84 workItemInfo.PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback;
85 workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute; 85 workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
86 workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects; 86 workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
87 workItemInfo.WorkItemPriority = wigStartInfo.WorkItemPriority; 87 workItemInfo.WorkItemPriority = wigStartInfo.WorkItemPriority;
88 88
89 WorkItem workItem = new WorkItem( 89 WorkItem workItem = new WorkItem(
90 workItemsGroup, 90 workItemsGroup,
91 workItemInfo, 91 workItemInfo,
92 callback, 92 callback,
93 state); 93 state);
94 return workItem; 94 return workItem;
95 } 95 }
96 96
97 /// <summary> 97 /// <summary>
98 /// Create a new work item 98 /// Create a new work item
99 /// </summary> 99 /// </summary>
100 /// <param name="workItemsGroup">The work items group</param> 100 /// <param name="workItemsGroup">The work items group</param>
101 /// <param name="wigStartInfo">Work item group start information</param> 101 /// <param name="wigStartInfo">Work item group start information</param>
102 /// <param name="callback">A callback to execute</param> 102 /// <param name="callback">A callback to execute</param>
103 /// <param name="state"> 103 /// <param name="state">
104 /// The context object of the work item. Used for passing arguments to the work item. 104 /// The context object of the work item. Used for passing arguments to the work item.
105 /// </param> 105 /// </param>
106 /// <param name="workItemPriority">The work item priority</param> 106 /// <param name="workItemPriority">The work item priority</param>
107 /// <returns>Returns a work item</returns> 107 /// <returns>Returns a work item</returns>
108 public static WorkItem CreateWorkItem( 108 public static WorkItem CreateWorkItem(
109 IWorkItemsGroup workItemsGroup, 109 IWorkItemsGroup workItemsGroup,
110 WIGStartInfo wigStartInfo, 110 WIGStartInfo wigStartInfo,
111 WorkItemCallback callback, 111 WorkItemCallback callback,
112 object state, 112 object state,
113 WorkItemPriority workItemPriority) 113 WorkItemPriority workItemPriority)
114 { 114 {
115 ValidateCallback(callback); 115 ValidateCallback(callback);
116 116
117 WorkItemInfo workItemInfo = new WorkItemInfo(); 117 WorkItemInfo workItemInfo = new WorkItemInfo();
118 workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext; 118 workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
119 workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext; 119 workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
120 workItemInfo.PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback; 120 workItemInfo.PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback;
121 workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute; 121 workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
122 workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects; 122 workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
123 workItemInfo.WorkItemPriority = workItemPriority; 123 workItemInfo.WorkItemPriority = workItemPriority;
124 124
125 WorkItem workItem = new WorkItem( 125 WorkItem workItem = new WorkItem(
126 workItemsGroup, 126 workItemsGroup,
127 workItemInfo, 127 workItemInfo,
128 callback, 128 callback,
129 state); 129 state);
130 130
131 return workItem; 131 return workItem;
132 } 132 }
133 133
134 /// <summary> 134 /// <summary>
135 /// Create a new work item 135 /// Create a new work item
136 /// </summary> 136 /// </summary>
137 /// <param name="workItemsGroup">The work items group</param> 137 /// <param name="workItemsGroup">The work items group</param>
138 /// <param name="wigStartInfo">Work item group start information</param> 138 /// <param name="wigStartInfo">Work item group start information</param>
139 /// <param name="workItemInfo">Work item information</param> 139 /// <param name="workItemInfo">Work item information</param>
140 /// <param name="callback">A callback to execute</param> 140 /// <param name="callback">A callback to execute</param>
141 /// <param name="state"> 141 /// <param name="state">
142 /// The context object of the work item. Used for passing arguments to the work item. 142 /// The context object of the work item. Used for passing arguments to the work item.
143 /// </param> 143 /// </param>
144 /// <returns>Returns a work item</returns> 144 /// <returns>Returns a work item</returns>
145 public static WorkItem CreateWorkItem( 145 public static WorkItem CreateWorkItem(
146 IWorkItemsGroup workItemsGroup, 146 IWorkItemsGroup workItemsGroup,
147 WIGStartInfo wigStartInfo, 147 WIGStartInfo wigStartInfo,
148 WorkItemInfo workItemInfo, 148 WorkItemInfo workItemInfo,
149 WorkItemCallback callback, 149 WorkItemCallback callback,
150 object state) 150 object state)
151 { 151 {
152 ValidateCallback(callback); 152 ValidateCallback(callback);
153 ValidateCallback(workItemInfo.PostExecuteWorkItemCallback); 153 ValidateCallback(workItemInfo.PostExecuteWorkItemCallback);
154 154
155 WorkItem workItem = new WorkItem( 155 WorkItem workItem = new WorkItem(
156 workItemsGroup, 156 workItemsGroup,
157 new WorkItemInfo(workItemInfo), 157 new WorkItemInfo(workItemInfo),
158 callback, 158 callback,
159 state); 159 state);
160 160
161 return workItem; 161 return workItem;
162 } 162 }
163 163
164 /// <summary> 164 /// <summary>
165 /// Create a new work item 165 /// Create a new work item
166 /// </summary> 166 /// </summary>
167 /// <param name="workItemsGroup">The work items group</param> 167 /// <param name="workItemsGroup">The work items group</param>
168 /// <param name="wigStartInfo">Work item group start information</param> 168 /// <param name="wigStartInfo">Work item group start information</param>
169 /// <param name="callback">A callback to execute</param> 169 /// <param name="callback">A callback to execute</param>
170 /// <param name="state"> 170 /// <param name="state">
171 /// The context object of the work item. Used for passing arguments to the work item. 171 /// The context object of the work item. Used for passing arguments to the work item.
172 /// </param> 172 /// </param>
173 /// <param name="postExecuteWorkItemCallback"> 173 /// <param name="postExecuteWorkItemCallback">
174 /// A delegate to call after the callback completion 174 /// A delegate to call after the callback completion
175 /// </param> 175 /// </param>
176 /// <returns>Returns a work item</returns> 176 /// <returns>Returns a work item</returns>
177 public static WorkItem CreateWorkItem( 177 public static WorkItem CreateWorkItem(
178 IWorkItemsGroup workItemsGroup, 178 IWorkItemsGroup workItemsGroup,
179 WIGStartInfo wigStartInfo, 179 WIGStartInfo wigStartInfo,
180 WorkItemCallback callback, 180 WorkItemCallback callback,
181 object state, 181 object state,
182 PostExecuteWorkItemCallback postExecuteWorkItemCallback) 182 PostExecuteWorkItemCallback postExecuteWorkItemCallback)
183 { 183 {
184 ValidateCallback(callback); 184 ValidateCallback(callback);
185 ValidateCallback(postExecuteWorkItemCallback); 185 ValidateCallback(postExecuteWorkItemCallback);
186 186
187 WorkItemInfo workItemInfo = new WorkItemInfo(); 187 WorkItemInfo workItemInfo = new WorkItemInfo();
188 workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext; 188 workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
189 workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext; 189 workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
190 workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback; 190 workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
191 workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute; 191 workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
192 workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects; 192 workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
193 workItemInfo.WorkItemPriority = wigStartInfo.WorkItemPriority; 193 workItemInfo.WorkItemPriority = wigStartInfo.WorkItemPriority;
194 194
195 WorkItem workItem = new WorkItem( 195 WorkItem workItem = new WorkItem(
196 workItemsGroup, 196 workItemsGroup,
197 workItemInfo, 197 workItemInfo,
198 callback, 198 callback,
199 state); 199 state);
200 200
201 return workItem; 201 return workItem;
202 } 202 }
203 203
204 /// <summary> 204 /// <summary>
205 /// Create a new work item 205 /// Create a new work item
206 /// </summary> 206 /// </summary>
207 /// <param name="workItemsGroup">The work items group</param> 207 /// <param name="workItemsGroup">The work items group</param>
208 /// <param name="wigStartInfo">Work item group start information</param> 208 /// <param name="wigStartInfo">Work item group start information</param>
209 /// <param name="callback">A callback to execute</param> 209 /// <param name="callback">A callback to execute</param>
210 /// <param name="state"> 210 /// <param name="state">
211 /// The context object of the work item. Used for passing arguments to the work item. 211 /// The context object of the work item. Used for passing arguments to the work item.
212 /// </param> 212 /// </param>
213 /// <param name="postExecuteWorkItemCallback"> 213 /// <param name="postExecuteWorkItemCallback">
214 /// A delegate to call after the callback completion 214 /// A delegate to call after the callback completion
215 /// </param> 215 /// </param>
216 /// <param name="workItemPriority">The work item priority</param> 216 /// <param name="workItemPriority">The work item priority</param>
217 /// <returns>Returns a work item</returns> 217 /// <returns>Returns a work item</returns>
218 public static WorkItem CreateWorkItem( 218 public static WorkItem CreateWorkItem(
219 IWorkItemsGroup workItemsGroup, 219 IWorkItemsGroup workItemsGroup,
220 WIGStartInfo wigStartInfo, 220 WIGStartInfo wigStartInfo,
221 WorkItemCallback callback, 221 WorkItemCallback callback,
222 object state, 222 object state,
223 PostExecuteWorkItemCallback postExecuteWorkItemCallback, 223 PostExecuteWorkItemCallback postExecuteWorkItemCallback,
224 WorkItemPriority workItemPriority) 224 WorkItemPriority workItemPriority)
225 { 225 {
226 ValidateCallback(callback); 226 ValidateCallback(callback);
227 ValidateCallback(postExecuteWorkItemCallback); 227 ValidateCallback(postExecuteWorkItemCallback);
228 228
229 WorkItemInfo workItemInfo = new WorkItemInfo(); 229 WorkItemInfo workItemInfo = new WorkItemInfo();
230 workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext; 230 workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
231 workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext; 231 workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
232 workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback; 232 workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
233 workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute; 233 workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
234 workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects; 234 workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
235 workItemInfo.WorkItemPriority = workItemPriority; 235 workItemInfo.WorkItemPriority = workItemPriority;
236 236
237 WorkItem workItem = new WorkItem( 237 WorkItem workItem = new WorkItem(
238 workItemsGroup, 238 workItemsGroup,
239 workItemInfo, 239 workItemInfo,
240 callback, 240 callback,
241 state); 241 state);
242 242
243 return workItem; 243 return workItem;
244 } 244 }
245 245
246 /// <summary> 246 /// <summary>
247 /// Create a new work item 247 /// Create a new work item
248 /// </summary> 248 /// </summary>
249 /// <param name="workItemsGroup">The work items group</param> 249 /// <param name="workItemsGroup">The work items group</param>
250 /// <param name="wigStartInfo">Work item group start information</param> 250 /// <param name="wigStartInfo">Work item group start information</param>
251 /// <param name="callback">A callback to execute</param> 251 /// <param name="callback">A callback to execute</param>
252 /// <param name="state"> 252 /// <param name="state">
253 /// The context object of the work item. Used for passing arguments to the work item. 253 /// The context object of the work item. Used for passing arguments to the work item.
254 /// </param> 254 /// </param>
255 /// <param name="postExecuteWorkItemCallback"> 255 /// <param name="postExecuteWorkItemCallback">
256 /// A delegate to call after the callback completion 256 /// A delegate to call after the callback completion
257 /// </param> 257 /// </param>
258 /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param> 258 /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
259 /// <returns>Returns a work item</returns> 259 /// <returns>Returns a work item</returns>
260 public static WorkItem CreateWorkItem( 260 public static WorkItem CreateWorkItem(
261 IWorkItemsGroup workItemsGroup, 261 IWorkItemsGroup workItemsGroup,
262 WIGStartInfo wigStartInfo, 262 WIGStartInfo wigStartInfo,
263 WorkItemCallback callback, 263 WorkItemCallback callback,
264 object state, 264 object state,
265 PostExecuteWorkItemCallback postExecuteWorkItemCallback, 265 PostExecuteWorkItemCallback postExecuteWorkItemCallback,
266 CallToPostExecute callToPostExecute) 266 CallToPostExecute callToPostExecute)
267 { 267 {
268 ValidateCallback(callback); 268 ValidateCallback(callback);
269 ValidateCallback(postExecuteWorkItemCallback); 269 ValidateCallback(postExecuteWorkItemCallback);
270 270
271 WorkItemInfo workItemInfo = new WorkItemInfo(); 271 WorkItemInfo workItemInfo = new WorkItemInfo();
272 workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext; 272 workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
273 workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext; 273 workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
274 workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback; 274 workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
275 workItemInfo.CallToPostExecute = callToPostExecute; 275 workItemInfo.CallToPostExecute = callToPostExecute;
276 workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects; 276 workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
277 workItemInfo.WorkItemPriority = wigStartInfo.WorkItemPriority; 277 workItemInfo.WorkItemPriority = wigStartInfo.WorkItemPriority;
278 278
279 WorkItem workItem = new WorkItem( 279 WorkItem workItem = new WorkItem(
280 workItemsGroup, 280 workItemsGroup,
281 workItemInfo, 281 workItemInfo,
282 callback, 282 callback,
283 state); 283 state);
284 284
285 return workItem; 285 return workItem;
286 } 286 }
287 287
288 /// <summary> 288 /// <summary>
289 /// Create a new work item 289 /// Create a new work item
290 /// </summary> 290 /// </summary>
291 /// <param name="workItemsGroup">The work items group</param> 291 /// <param name="workItemsGroup">The work items group</param>
292 /// <param name="wigStartInfo">Work item group start information</param> 292 /// <param name="wigStartInfo">Work item group start information</param>
293 /// <param name="callback">A callback to execute</param> 293 /// <param name="callback">A callback to execute</param>
294 /// <param name="state"> 294 /// <param name="state">
295 /// The context object of the work item. Used for passing arguments to the work item. 295 /// The context object of the work item. Used for passing arguments to the work item.
296 /// </param> 296 /// </param>
297 /// <param name="postExecuteWorkItemCallback"> 297 /// <param name="postExecuteWorkItemCallback">
298 /// A delegate to call after the callback completion 298 /// A delegate to call after the callback completion
299 /// </param> 299 /// </param>
300 /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param> 300 /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
301 /// <param name="workItemPriority">The work item priority</param> 301 /// <param name="workItemPriority">The work item priority</param>
302 /// <returns>Returns a work item</returns> 302 /// <returns>Returns a work item</returns>
303 public static WorkItem CreateWorkItem( 303 public static WorkItem CreateWorkItem(
304 IWorkItemsGroup workItemsGroup, 304 IWorkItemsGroup workItemsGroup,
305 WIGStartInfo wigStartInfo, 305 WIGStartInfo wigStartInfo,
306 WorkItemCallback callback, 306 WorkItemCallback callback,
307 object state, 307 object state,
308 PostExecuteWorkItemCallback postExecuteWorkItemCallback, 308 PostExecuteWorkItemCallback postExecuteWorkItemCallback,
309 CallToPostExecute callToPostExecute, 309 CallToPostExecute callToPostExecute,
310 WorkItemPriority workItemPriority) 310 WorkItemPriority workItemPriority)
311 { 311 {
312 312
313 ValidateCallback(callback); 313 ValidateCallback(callback);
314 ValidateCallback(postExecuteWorkItemCallback); 314 ValidateCallback(postExecuteWorkItemCallback);
315 315
316 WorkItemInfo workItemInfo = new WorkItemInfo(); 316 WorkItemInfo workItemInfo = new WorkItemInfo();
317 workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext; 317 workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
318 workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext; 318 workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
319 workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback; 319 workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
320 workItemInfo.CallToPostExecute = callToPostExecute; 320 workItemInfo.CallToPostExecute = callToPostExecute;
321 workItemInfo.WorkItemPriority = workItemPriority; 321 workItemInfo.WorkItemPriority = workItemPriority;
322 workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects; 322 workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
323 323
324 WorkItem workItem = new WorkItem( 324 WorkItem workItem = new WorkItem(
325 workItemsGroup, 325 workItemsGroup,
326 workItemInfo, 326 workItemInfo,
327 callback, 327 callback,
328 state); 328 state);
329 329
330 return workItem; 330 return workItem;
331 } 331 }
332 332
333 private static void ValidateCallback(Delegate callback) 333 private static void ValidateCallback(Delegate callback)
334 { 334 {
335 if (callback != null && callback.GetInvocationList().Length > 1) 335 if (callback != null && callback.GetInvocationList().Length > 1)
336 { 336 {
337 throw new NotSupportedException("SmartThreadPool doesn't support delegates chains"); 337 throw new NotSupportedException("SmartThreadPool doesn't support delegates chains");
338 } 338 }
339 } 339 }
340 } 340 }
341 341
342 #endregion 342 #endregion
343} 343}
diff --git a/ThirdParty/SmartThreadPool/WorkItemInfo.cs b/ThirdParty/SmartThreadPool/WorkItemInfo.cs
index 5fbceb8..0d7fc85 100644
--- a/ThirdParty/SmartThreadPool/WorkItemInfo.cs
+++ b/ThirdParty/SmartThreadPool/WorkItemInfo.cs
@@ -1,69 +1,69 @@
1namespace Amib.Threading 1namespace Amib.Threading
2{ 2{
3 #region WorkItemInfo class 3 #region WorkItemInfo class
4 4
5 /// <summary> 5 /// <summary>
6 /// Summary description for WorkItemInfo. 6 /// Summary description for WorkItemInfo.
7 /// </summary> 7 /// </summary>
8 public class WorkItemInfo 8 public class WorkItemInfo
9 { 9 {
10 public WorkItemInfo() 10 public WorkItemInfo()
11 { 11 {
12 UseCallerCallContext = SmartThreadPool.DefaultUseCallerCallContext; 12 UseCallerCallContext = SmartThreadPool.DefaultUseCallerCallContext;
13 UseCallerHttpContext = SmartThreadPool.DefaultUseCallerHttpContext; 13 UseCallerHttpContext = SmartThreadPool.DefaultUseCallerHttpContext;
14 DisposeOfStateObjects = SmartThreadPool.DefaultDisposeOfStateObjects; 14 DisposeOfStateObjects = SmartThreadPool.DefaultDisposeOfStateObjects;
15 CallToPostExecute = SmartThreadPool.DefaultCallToPostExecute; 15 CallToPostExecute = SmartThreadPool.DefaultCallToPostExecute;
16 PostExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback; 16 PostExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback;
17 WorkItemPriority = SmartThreadPool.DefaultWorkItemPriority; 17 WorkItemPriority = SmartThreadPool.DefaultWorkItemPriority;
18 } 18 }
19 19
20 public WorkItemInfo(WorkItemInfo workItemInfo) 20 public WorkItemInfo(WorkItemInfo workItemInfo)
21 { 21 {
22 UseCallerCallContext = workItemInfo.UseCallerCallContext; 22 UseCallerCallContext = workItemInfo.UseCallerCallContext;
23 UseCallerHttpContext = workItemInfo.UseCallerHttpContext; 23 UseCallerHttpContext = workItemInfo.UseCallerHttpContext;
24 DisposeOfStateObjects = workItemInfo.DisposeOfStateObjects; 24 DisposeOfStateObjects = workItemInfo.DisposeOfStateObjects;
25 CallToPostExecute = workItemInfo.CallToPostExecute; 25 CallToPostExecute = workItemInfo.CallToPostExecute;
26 PostExecuteWorkItemCallback = workItemInfo.PostExecuteWorkItemCallback; 26 PostExecuteWorkItemCallback = workItemInfo.PostExecuteWorkItemCallback;
27 WorkItemPriority = workItemInfo.WorkItemPriority; 27 WorkItemPriority = workItemInfo.WorkItemPriority;
28 Timeout = workItemInfo.Timeout; 28 Timeout = workItemInfo.Timeout;
29 } 29 }
30 30
31 /// <summary> 31 /// <summary>
32 /// Get/Set if to use the caller's security context 32 /// Get/Set if to use the caller's security context
33 /// </summary> 33 /// </summary>
34 public bool UseCallerCallContext { get; set; } 34 public bool UseCallerCallContext { get; set; }
35 35
36 /// <summary> 36 /// <summary>
37 /// Get/Set if to use the caller's HTTP context 37 /// Get/Set if to use the caller's HTTP context
38 /// </summary> 38 /// </summary>
39 public bool UseCallerHttpContext { get; set; } 39 public bool UseCallerHttpContext { get; set; }
40 40
41 /// <summary> 41 /// <summary>
42 /// Get/Set if to dispose of the state object of a work item 42 /// Get/Set if to dispose of the state object of a work item
43 /// </summary> 43 /// </summary>
44 public bool DisposeOfStateObjects { get; set; } 44 public bool DisposeOfStateObjects { get; set; }
45 45
46 /// <summary> 46 /// <summary>
47 /// Get/Set the run the post execute options 47 /// Get/Set the run the post execute options
48 /// </summary> 48 /// </summary>
49 public CallToPostExecute CallToPostExecute { get; set; } 49 public CallToPostExecute CallToPostExecute { get; set; }
50 50
51 /// <summary> 51 /// <summary>
52 /// Get/Set the post execute callback 52 /// Get/Set the post execute callback
53 /// </summary> 53 /// </summary>
54 public PostExecuteWorkItemCallback PostExecuteWorkItemCallback { get; set; } 54 public PostExecuteWorkItemCallback PostExecuteWorkItemCallback { get; set; }
55 55
56 /// <summary> 56 /// <summary>
57 /// Get/Set the work item's priority 57 /// Get/Set the work item's priority
58 /// </summary> 58 /// </summary>
59 public WorkItemPriority WorkItemPriority { get; set; } 59 public WorkItemPriority WorkItemPriority { get; set; }
60 60
61 /// <summary> 61 /// <summary>
62 /// Get/Set the work item's timout in milliseconds. 62 /// Get/Set the work item's timout in milliseconds.
63 /// This is a passive timout. When the timout expires the work item won't be actively aborted! 63 /// This is a passive timout. When the timout expires the work item won't be actively aborted!
64 /// </summary> 64 /// </summary>
65 public long Timeout { get; set; } 65 public long Timeout { get; set; }
66 } 66 }
67 67
68 #endregion 68 #endregion
69} 69}
diff --git a/ThirdParty/SmartThreadPool/WorkItemResultTWrapper.cs b/ThirdParty/SmartThreadPool/WorkItemResultTWrapper.cs
index a0bf8b8..d1eff95 100644
--- a/ThirdParty/SmartThreadPool/WorkItemResultTWrapper.cs
+++ b/ThirdParty/SmartThreadPool/WorkItemResultTWrapper.cs
@@ -1,128 +1,128 @@
1using System; 1using System;
2using System.Threading; 2using System.Threading;
3 3
4namespace Amib.Threading.Internal 4namespace Amib.Threading.Internal
5{ 5{
6 #region WorkItemResultTWrapper class 6 #region WorkItemResultTWrapper class
7 7
8 internal class WorkItemResultTWrapper<TResult> : IWorkItemResult<TResult>, IInternalWaitableResult 8 internal class WorkItemResultTWrapper<TResult> : IWorkItemResult<TResult>, IInternalWaitableResult
9 { 9 {
10 private readonly IWorkItemResult _workItemResult; 10 private readonly IWorkItemResult _workItemResult;
11 11
12 public WorkItemResultTWrapper(IWorkItemResult workItemResult) 12 public WorkItemResultTWrapper(IWorkItemResult workItemResult)
13 { 13 {
14 _workItemResult = workItemResult; 14 _workItemResult = workItemResult;
15 } 15 }
16 16
17 #region IWorkItemResult<TResult> Members 17 #region IWorkItemResult<TResult> Members
18 18
19 public TResult GetResult() 19 public TResult GetResult()
20 { 20 {
21 return (TResult)_workItemResult.GetResult(); 21 return (TResult)_workItemResult.GetResult();
22 } 22 }
23 23
24 public TResult GetResult(int millisecondsTimeout, bool exitContext) 24 public TResult GetResult(int millisecondsTimeout, bool exitContext)
25 { 25 {
26 return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext); 26 return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext);
27 } 27 }
28 28
29 public TResult GetResult(TimeSpan timeout, bool exitContext) 29 public TResult GetResult(TimeSpan timeout, bool exitContext)
30 { 30 {
31 return (TResult)_workItemResult.GetResult(timeout, exitContext); 31 return (TResult)_workItemResult.GetResult(timeout, exitContext);
32 } 32 }
33 33
34 public TResult GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle) 34 public TResult GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle)
35 { 35 {
36 return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle); 36 return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle);
37 } 37 }
38 38
39 public TResult GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle) 39 public TResult GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle)
40 { 40 {
41 return (TResult)_workItemResult.GetResult(timeout, exitContext, cancelWaitHandle); 41 return (TResult)_workItemResult.GetResult(timeout, exitContext, cancelWaitHandle);
42 } 42 }
43 43
44 public TResult GetResult(out Exception e) 44 public TResult GetResult(out Exception e)
45 { 45 {
46 return (TResult)_workItemResult.GetResult(out e); 46 return (TResult)_workItemResult.GetResult(out e);
47 } 47 }
48 48
49 public TResult GetResult(int millisecondsTimeout, bool exitContext, out Exception e) 49 public TResult GetResult(int millisecondsTimeout, bool exitContext, out Exception e)
50 { 50 {
51 return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext, out e); 51 return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext, out e);
52 } 52 }
53 53
54 public TResult GetResult(TimeSpan timeout, bool exitContext, out Exception e) 54 public TResult GetResult(TimeSpan timeout, bool exitContext, out Exception e)
55 { 55 {
56 return (TResult)_workItemResult.GetResult(timeout, exitContext, out e); 56 return (TResult)_workItemResult.GetResult(timeout, exitContext, out e);
57 } 57 }
58 58
59 public TResult GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e) 59 public TResult GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
60 { 60 {
61 return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e); 61 return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e);
62 } 62 }
63 63
64 public TResult GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e) 64 public TResult GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
65 { 65 {
66 return (TResult)_workItemResult.GetResult(timeout, exitContext, cancelWaitHandle, out e); 66 return (TResult)_workItemResult.GetResult(timeout, exitContext, cancelWaitHandle, out e);
67 } 67 }
68 68
69 public bool IsCompleted 69 public bool IsCompleted
70 { 70 {
71 get { return _workItemResult.IsCompleted; } 71 get { return _workItemResult.IsCompleted; }
72 } 72 }
73 73
74 public bool IsCanceled 74 public bool IsCanceled
75 { 75 {
76 get { return _workItemResult.IsCanceled; } 76 get { return _workItemResult.IsCanceled; }
77 } 77 }
78 78
79 public object State 79 public object State
80 { 80 {
81 get { return _workItemResult.State; } 81 get { return _workItemResult.State; }
82 } 82 }
83 83
84 public bool Cancel() 84 public bool Cancel()
85 { 85 {
86 return _workItemResult.Cancel(); 86 return _workItemResult.Cancel();
87 } 87 }
88 88
89 public bool Cancel(bool abortExecution) 89 public bool Cancel(bool abortExecution)
90 { 90 {
91 return _workItemResult.Cancel(abortExecution); 91 return _workItemResult.Cancel(abortExecution);
92 } 92 }
93 93
94 public WorkItemPriority WorkItemPriority 94 public WorkItemPriority WorkItemPriority
95 { 95 {
96 get { return _workItemResult.WorkItemPriority; } 96 get { return _workItemResult.WorkItemPriority; }
97 } 97 }
98 98
99 public TResult Result 99 public TResult Result
100 { 100 {
101 get { return (TResult)_workItemResult.Result; } 101 get { return (TResult)_workItemResult.Result; }
102 } 102 }
103 103
104 public object Exception 104 public object Exception
105 { 105 {
106 get { return (TResult)_workItemResult.Exception; } 106 get { return (TResult)_workItemResult.Exception; }
107 } 107 }
108 108
109 #region IInternalWorkItemResult Members 109 #region IInternalWorkItemResult Members
110 110
111 public IWorkItemResult GetWorkItemResult() 111 public IWorkItemResult GetWorkItemResult()
112 { 112 {
113 return _workItemResult.GetWorkItemResult(); 113 return _workItemResult.GetWorkItemResult();
114 } 114 }
115 115
116 public IWorkItemResult<TRes> GetWorkItemResultT<TRes>() 116 public IWorkItemResult<TRes> GetWorkItemResultT<TRes>()
117 { 117 {
118 return (IWorkItemResult<TRes>)this; 118 return (IWorkItemResult<TRes>)this;
119 } 119 }
120 120
121 #endregion 121 #endregion
122 122
123 #endregion 123 #endregion
124 } 124 }
125 125
126 #endregion 126 #endregion
127 127
128} 128}
diff --git a/ThirdParty/SmartThreadPool/WorkItemsGroup.cs b/ThirdParty/SmartThreadPool/WorkItemsGroup.cs
index 67dcbdd..d9d34ac 100644
--- a/ThirdParty/SmartThreadPool/WorkItemsGroup.cs
+++ b/ThirdParty/SmartThreadPool/WorkItemsGroup.cs
@@ -1,361 +1,361 @@
1using System; 1using System;
2using System.Threading; 2using System.Threading;
3using System.Runtime.CompilerServices; 3using System.Runtime.CompilerServices;
4using System.Diagnostics; 4using System.Diagnostics;
5 5
6namespace Amib.Threading.Internal 6namespace Amib.Threading.Internal
7{ 7{
8 8
9 #region WorkItemsGroup class 9 #region WorkItemsGroup class
10 10
11 /// <summary> 11 /// <summary>
12 /// Summary description for WorkItemsGroup. 12 /// Summary description for WorkItemsGroup.
13 /// </summary> 13 /// </summary>
14 public class WorkItemsGroup : WorkItemsGroupBase 14 public class WorkItemsGroup : WorkItemsGroupBase
15 { 15 {
16 #region Private members 16 #region Private members
17 17
18 private readonly object _lock = new object(); 18 private readonly object _lock = new object();
19 19
20 /// <summary> 20 /// <summary>
21 /// A reference to the SmartThreadPool instance that created this 21 /// A reference to the SmartThreadPool instance that created this
22 /// WorkItemsGroup. 22 /// WorkItemsGroup.
23 /// </summary> 23 /// </summary>
24 private readonly SmartThreadPool _stp; 24 private readonly SmartThreadPool _stp;
25 25
26 /// <summary> 26 /// <summary>
27 /// The OnIdle event 27 /// The OnIdle event
28 /// </summary> 28 /// </summary>
29 private event WorkItemsGroupIdleHandler _onIdle; 29 private event WorkItemsGroupIdleHandler _onIdle;
30 30
31 /// <summary> 31 /// <summary>
32 /// A flag to indicate if the Work Items Group is now suspended. 32 /// A flag to indicate if the Work Items Group is now suspended.
33 /// </summary> 33 /// </summary>
34 private bool _isSuspended; 34 private bool _isSuspended;
35 35
36 /// <summary> 36 /// <summary>
37 /// Defines how many work items of this WorkItemsGroup can run at once. 37 /// Defines how many work items of this WorkItemsGroup can run at once.
38 /// </summary> 38 /// </summary>
39 private int _concurrency; 39 private int _concurrency;
40 40
41 /// <summary> 41 /// <summary>
42 /// Priority queue to hold work items before they are passed 42 /// Priority queue to hold work items before they are passed
43 /// to the SmartThreadPool. 43 /// to the SmartThreadPool.
44 /// </summary> 44 /// </summary>
45 private readonly PriorityQueue _workItemsQueue; 45 private readonly PriorityQueue _workItemsQueue;
46 46
47 /// <summary> 47 /// <summary>
48 /// Indicate how many work items are waiting in the SmartThreadPool 48 /// Indicate how many work items are waiting in the SmartThreadPool
49 /// queue. 49 /// queue.
50 /// This value is used to apply the concurrency. 50 /// This value is used to apply the concurrency.
51 /// </summary> 51 /// </summary>
52 private int _workItemsInStpQueue; 52 private int _workItemsInStpQueue;
53 53
54 /// <summary> 54 /// <summary>
55 /// Indicate how many work items are currently running in the SmartThreadPool. 55 /// Indicate how many work items are currently running in the SmartThreadPool.
56 /// This value is used with the Cancel, to calculate if we can send new 56 /// This value is used with the Cancel, to calculate if we can send new
57 /// work items to the STP. 57 /// work items to the STP.
58 /// </summary> 58 /// </summary>
59 private int _workItemsExecutingInStp = 0; 59 private int _workItemsExecutingInStp = 0;
60 60
61 /// <summary> 61 /// <summary>
62 /// WorkItemsGroup start information 62 /// WorkItemsGroup start information
63 /// </summary> 63 /// </summary>
64 private readonly WIGStartInfo _workItemsGroupStartInfo; 64 private readonly WIGStartInfo _workItemsGroupStartInfo;
65 65
66 /// <summary> 66 /// <summary>
67 /// Signaled when all of the WorkItemsGroup's work item completed. 67 /// Signaled when all of the WorkItemsGroup's work item completed.
68 /// </summary> 68 /// </summary>
69 //private readonly ManualResetEvent _isIdleWaitHandle = new ManualResetEvent(true); 69 //private readonly ManualResetEvent _isIdleWaitHandle = new ManualResetEvent(true);
70 private readonly ManualResetEvent _isIdleWaitHandle = EventWaitHandleFactory.CreateManualResetEvent(true); 70 private readonly ManualResetEvent _isIdleWaitHandle = EventWaitHandleFactory.CreateManualResetEvent(true);
71 71
72 /// <summary> 72 /// <summary>
73 /// A common object for all the work items that this work items group 73 /// A common object for all the work items that this work items group
74 /// generate so we can mark them to cancel in O(1) 74 /// generate so we can mark them to cancel in O(1)
75 /// </summary> 75 /// </summary>
76 private CanceledWorkItemsGroup _canceledWorkItemsGroup = new CanceledWorkItemsGroup(); 76 private CanceledWorkItemsGroup _canceledWorkItemsGroup = new CanceledWorkItemsGroup();
77 77
78 #endregion 78 #endregion
79 79
80 #region Construction 80 #region Construction
81 81
82 public WorkItemsGroup( 82 public WorkItemsGroup(
83 SmartThreadPool stp, 83 SmartThreadPool stp,
84 int concurrency, 84 int concurrency,
85 WIGStartInfo wigStartInfo) 85 WIGStartInfo wigStartInfo)
86 { 86 {
87 if (concurrency <= 0) 87 if (concurrency <= 0)
88 { 88 {
89 throw new ArgumentOutOfRangeException( 89 throw new ArgumentOutOfRangeException(
90 "concurrency", 90 "concurrency",
91#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE) 91#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
92 concurrency, 92 concurrency,
93#endif 93#endif
94 "concurrency must be greater than zero"); 94 "concurrency must be greater than zero");
95 } 95 }
96 _stp = stp; 96 _stp = stp;
97 _concurrency = concurrency; 97 _concurrency = concurrency;
98 _workItemsGroupStartInfo = new WIGStartInfo(wigStartInfo).AsReadOnly(); 98 _workItemsGroupStartInfo = new WIGStartInfo(wigStartInfo).AsReadOnly();
99 _workItemsQueue = new PriorityQueue(); 99 _workItemsQueue = new PriorityQueue();
100 Name = "WorkItemsGroup"; 100 Name = "WorkItemsGroup";
101 101
102 // The _workItemsInStpQueue gets the number of currently executing work items, 102 // The _workItemsInStpQueue gets the number of currently executing work items,
103 // because once a work item is executing, it cannot be cancelled. 103 // because once a work item is executing, it cannot be cancelled.
104 _workItemsInStpQueue = _workItemsExecutingInStp; 104 _workItemsInStpQueue = _workItemsExecutingInStp;
105 105
106 _isSuspended = _workItemsGroupStartInfo.StartSuspended; 106 _isSuspended = _workItemsGroupStartInfo.StartSuspended;
107 } 107 }
108 108
109 #endregion 109 #endregion
110 110
111 #region WorkItemsGroupBase Overrides 111 #region WorkItemsGroupBase Overrides
112 112
113 public override int Concurrency 113 public override int Concurrency
114 { 114 {
115 get { return _concurrency; } 115 get { return _concurrency; }
116 set 116 set
117 { 117 {
118 Debug.Assert(value > 0); 118 Debug.Assert(value > 0);
119 119
120 int diff = value - _concurrency; 120 int diff = value - _concurrency;
121 _concurrency = value; 121 _concurrency = value;
122 if (diff > 0) 122 if (diff > 0)
123 { 123 {
124 EnqueueToSTPNextNWorkItem(diff); 124 EnqueueToSTPNextNWorkItem(diff);
125 } 125 }
126 } 126 }
127 } 127 }
128 128
129 public override int WaitingCallbacks 129 public override int WaitingCallbacks
130 { 130 {
131 get { return _workItemsQueue.Count; } 131 get { return _workItemsQueue.Count; }
132 } 132 }
133 133
134 public override object[] GetStates() 134 public override object[] GetStates()
135 { 135 {
136 lock (_lock) 136 lock (_lock)
137 { 137 {
138 object[] states = new object[_workItemsQueue.Count]; 138 object[] states = new object[_workItemsQueue.Count];
139 int i = 0; 139 int i = 0;
140 foreach (WorkItem workItem in _workItemsQueue) 140 foreach (WorkItem workItem in _workItemsQueue)
141 { 141 {
142 states[i] = workItem.GetWorkItemResult().State; 142 states[i] = workItem.GetWorkItemResult().State;
143 ++i; 143 ++i;
144 } 144 }
145 return states; 145 return states;
146 } 146 }
147 } 147 }
148 148
149 /// <summary> 149 /// <summary>
150 /// WorkItemsGroup start information 150 /// WorkItemsGroup start information
151 /// </summary> 151 /// </summary>
152 public override WIGStartInfo WIGStartInfo 152 public override WIGStartInfo WIGStartInfo
153 { 153 {
154 get { return _workItemsGroupStartInfo; } 154 get { return _workItemsGroupStartInfo; }
155 } 155 }
156 156
157 /// <summary> 157 /// <summary>
158 /// Start the Work Items Group if it was started suspended 158 /// Start the Work Items Group if it was started suspended
159 /// </summary> 159 /// </summary>
160 public override void Start() 160 public override void Start()
161 { 161 {
162 // If the Work Items Group already started then quit 162 // If the Work Items Group already started then quit
163 if (!_isSuspended) 163 if (!_isSuspended)
164 { 164 {
165 return; 165 return;
166 } 166 }
167 _isSuspended = false; 167 _isSuspended = false;
168 168
169 EnqueueToSTPNextNWorkItem(Math.Min(_workItemsQueue.Count, _concurrency)); 169 EnqueueToSTPNextNWorkItem(Math.Min(_workItemsQueue.Count, _concurrency));
170 } 170 }
171 171
172 public override void Cancel(bool abortExecution) 172 public override void Cancel(bool abortExecution)
173 { 173 {
174 lock (_lock) 174 lock (_lock)
175 { 175 {
176 _canceledWorkItemsGroup.IsCanceled = true; 176 _canceledWorkItemsGroup.IsCanceled = true;
177 _workItemsQueue.Clear(); 177 _workItemsQueue.Clear();
178 _workItemsInStpQueue = 0; 178 _workItemsInStpQueue = 0;
179 _canceledWorkItemsGroup = new CanceledWorkItemsGroup(); 179 _canceledWorkItemsGroup = new CanceledWorkItemsGroup();
180 } 180 }
181 181
182 if (abortExecution) 182 if (abortExecution)
183 { 183 {
184 _stp.CancelAbortWorkItemsGroup(this); 184 _stp.CancelAbortWorkItemsGroup(this);
185 } 185 }
186 } 186 }
187 187
188 /// <summary> 188 /// <summary>
189 /// Wait for the thread pool to be idle 189 /// Wait for the thread pool to be idle
190 /// </summary> 190 /// </summary>
191 public override bool WaitForIdle(int millisecondsTimeout) 191 public override bool WaitForIdle(int millisecondsTimeout)
192 { 192 {
193 SmartThreadPool.ValidateWorkItemsGroupWaitForIdle(this); 193 SmartThreadPool.ValidateWorkItemsGroupWaitForIdle(this);
194 return STPEventWaitHandle.WaitOne(_isIdleWaitHandle, millisecondsTimeout, false); 194 return STPEventWaitHandle.WaitOne(_isIdleWaitHandle, millisecondsTimeout, false);
195 } 195 }
196 196
197 public override event WorkItemsGroupIdleHandler OnIdle 197 public override event WorkItemsGroupIdleHandler OnIdle
198 { 198 {
199 add { _onIdle += value; } 199 add { _onIdle += value; }
200 remove { _onIdle -= value; } 200 remove { _onIdle -= value; }
201 } 201 }
202 202
203 #endregion 203 #endregion
204 204
205 #region Private methods 205 #region Private methods
206 206
207 private void RegisterToWorkItemCompletion(IWorkItemResult wir) 207 private void RegisterToWorkItemCompletion(IWorkItemResult wir)
208 { 208 {
209 IInternalWorkItemResult iwir = (IInternalWorkItemResult)wir; 209 IInternalWorkItemResult iwir = (IInternalWorkItemResult)wir;
210 iwir.OnWorkItemStarted += OnWorkItemStartedCallback; 210 iwir.OnWorkItemStarted += OnWorkItemStartedCallback;
211 iwir.OnWorkItemCompleted += OnWorkItemCompletedCallback; 211 iwir.OnWorkItemCompleted += OnWorkItemCompletedCallback;
212 } 212 }
213 213
214 public void OnSTPIsStarting() 214 public void OnSTPIsStarting()
215 { 215 {
216 if (_isSuspended) 216 if (_isSuspended)
217 { 217 {
218 return; 218 return;
219 } 219 }
220 220
221 EnqueueToSTPNextNWorkItem(_concurrency); 221 EnqueueToSTPNextNWorkItem(_concurrency);
222 } 222 }
223 223
224 public void EnqueueToSTPNextNWorkItem(int count) 224 public void EnqueueToSTPNextNWorkItem(int count)
225 { 225 {
226 for (int i = 0; i < count; ++i) 226 for (int i = 0; i < count; ++i)
227 { 227 {
228 EnqueueToSTPNextWorkItem(null, false); 228 EnqueueToSTPNextWorkItem(null, false);
229 } 229 }
230 } 230 }
231 231
232 private object FireOnIdle(object state) 232 private object FireOnIdle(object state)
233 { 233 {
234 FireOnIdleImpl(_onIdle); 234 FireOnIdleImpl(_onIdle);
235 return null; 235 return null;
236 } 236 }
237 237
238 [MethodImpl(MethodImplOptions.NoInlining)] 238 [MethodImpl(MethodImplOptions.NoInlining)]
239 private void FireOnIdleImpl(WorkItemsGroupIdleHandler onIdle) 239 private void FireOnIdleImpl(WorkItemsGroupIdleHandler onIdle)
240 { 240 {
241 if(null == onIdle) 241 if(null == onIdle)
242 { 242 {
243 return; 243 return;
244 } 244 }
245 245
246 Delegate[] delegates = onIdle.GetInvocationList(); 246 Delegate[] delegates = onIdle.GetInvocationList();
247 foreach(WorkItemsGroupIdleHandler eh in delegates) 247 foreach(WorkItemsGroupIdleHandler eh in delegates)
248 { 248 {
249 try 249 try
250 { 250 {
251 eh(this); 251 eh(this);
252 } 252 }
253 catch { } // Suppress exceptions 253 catch { } // Suppress exceptions
254 } 254 }
255 } 255 }
256 256
257 private void OnWorkItemStartedCallback(WorkItem workItem) 257 private void OnWorkItemStartedCallback(WorkItem workItem)
258 { 258 {
259 lock(_lock) 259 lock(_lock)
260 { 260 {
261 ++_workItemsExecutingInStp; 261 ++_workItemsExecutingInStp;
262 } 262 }
263 } 263 }
264 264
265 private void OnWorkItemCompletedCallback(WorkItem workItem) 265 private void OnWorkItemCompletedCallback(WorkItem workItem)
266 { 266 {
267 EnqueueToSTPNextWorkItem(null, true); 267 EnqueueToSTPNextWorkItem(null, true);
268 } 268 }
269 269
270 internal override void Enqueue(WorkItem workItem) 270 internal override void Enqueue(WorkItem workItem)
271 { 271 {
272 EnqueueToSTPNextWorkItem(workItem); 272 EnqueueToSTPNextWorkItem(workItem);
273 } 273 }
274 274
275 private void EnqueueToSTPNextWorkItem(WorkItem workItem) 275 private void EnqueueToSTPNextWorkItem(WorkItem workItem)
276 { 276 {
277 EnqueueToSTPNextWorkItem(workItem, false); 277 EnqueueToSTPNextWorkItem(workItem, false);
278 } 278 }
279 279
280 private void EnqueueToSTPNextWorkItem(WorkItem workItem, bool decrementWorkItemsInStpQueue) 280 private void EnqueueToSTPNextWorkItem(WorkItem workItem, bool decrementWorkItemsInStpQueue)
281 { 281 {
282 lock(_lock) 282 lock(_lock)
283 { 283 {
284 // Got here from OnWorkItemCompletedCallback() 284 // Got here from OnWorkItemCompletedCallback()
285 if (decrementWorkItemsInStpQueue) 285 if (decrementWorkItemsInStpQueue)
286 { 286 {
287 --_workItemsInStpQueue; 287 --_workItemsInStpQueue;
288 288
289 if(_workItemsInStpQueue < 0) 289 if(_workItemsInStpQueue < 0)
290 { 290 {
291 _workItemsInStpQueue = 0; 291 _workItemsInStpQueue = 0;
292 } 292 }
293 293
294 --_workItemsExecutingInStp; 294 --_workItemsExecutingInStp;
295 295
296 if(_workItemsExecutingInStp < 0) 296 if(_workItemsExecutingInStp < 0)
297 { 297 {
298 _workItemsExecutingInStp = 0; 298 _workItemsExecutingInStp = 0;
299 } 299 }
300 } 300 }
301 301
302 // If the work item is not null then enqueue it 302 // If the work item is not null then enqueue it
303 if (null != workItem) 303 if (null != workItem)
304 { 304 {
305 workItem.CanceledWorkItemsGroup = _canceledWorkItemsGroup; 305 workItem.CanceledWorkItemsGroup = _canceledWorkItemsGroup;
306 306
307 RegisterToWorkItemCompletion(workItem.GetWorkItemResult()); 307 RegisterToWorkItemCompletion(workItem.GetWorkItemResult());
308 _workItemsQueue.Enqueue(workItem); 308 _workItemsQueue.Enqueue(workItem);
309 //_stp.IncrementWorkItemsCount(); 309 //_stp.IncrementWorkItemsCount();
310 310
311 if ((1 == _workItemsQueue.Count) && 311 if ((1 == _workItemsQueue.Count) &&
312 (0 == _workItemsInStpQueue)) 312 (0 == _workItemsInStpQueue))
313 { 313 {
314 _stp.RegisterWorkItemsGroup(this); 314 _stp.RegisterWorkItemsGroup(this);
315 IsIdle = false; 315 IsIdle = false;
316 _isIdleWaitHandle.Reset(); 316 _isIdleWaitHandle.Reset();
317 } 317 }
318 } 318 }
319 319
320 // If the work items queue of the group is empty than quit 320 // If the work items queue of the group is empty than quit
321 if (0 == _workItemsQueue.Count) 321 if (0 == _workItemsQueue.Count)
322 { 322 {
323 if (0 == _workItemsInStpQueue) 323 if (0 == _workItemsInStpQueue)
324 { 324 {
325 _stp.UnregisterWorkItemsGroup(this); 325 _stp.UnregisterWorkItemsGroup(this);
326 IsIdle = true; 326 IsIdle = true;
327 _isIdleWaitHandle.Set(); 327 _isIdleWaitHandle.Set();
328 if (decrementWorkItemsInStpQueue && _onIdle != null && _onIdle.GetInvocationList().Length > 0) 328 if (decrementWorkItemsInStpQueue && _onIdle != null && _onIdle.GetInvocationList().Length > 0)
329 { 329 {
330 _stp.QueueWorkItem(new WorkItemCallback(FireOnIdle)); 330 _stp.QueueWorkItem(new WorkItemCallback(FireOnIdle));
331 } 331 }
332 } 332 }
333 return; 333 return;
334 } 334 }
335 335
336 if (!_isSuspended) 336 if (!_isSuspended)
337 { 337 {
338 if (_workItemsInStpQueue < _concurrency) 338 if (_workItemsInStpQueue < _concurrency)
339 { 339 {
340 WorkItem nextWorkItem = _workItemsQueue.Dequeue() as WorkItem; 340 WorkItem nextWorkItem = _workItemsQueue.Dequeue() as WorkItem;
341 try 341 try
342 { 342 {
343 _stp.Enqueue(nextWorkItem); 343 _stp.Enqueue(nextWorkItem);
344 } 344 }
345 catch (ObjectDisposedException e) 345 catch (ObjectDisposedException e)
346 { 346 {
347 e.GetHashCode(); 347 e.GetHashCode();
348 // The STP has been shutdown 348 // The STP has been shutdown
349 } 349 }
350 350
351 ++_workItemsInStpQueue; 351 ++_workItemsInStpQueue;
352 } 352 }
353 } 353 }
354 } 354 }
355 } 355 }
356 356
357 #endregion 357 #endregion
358 } 358 }
359 359
360 #endregion 360 #endregion
361} 361}
diff --git a/ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs b/ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs
index 429de12..27fae5e 100644
--- a/ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs
+++ b/ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs
@@ -1,471 +1,471 @@
1using System; 1using System;
2using System.Threading; 2using System.Threading;
3 3
4namespace Amib.Threading.Internal 4namespace Amib.Threading.Internal
5{ 5{
6 public abstract class WorkItemsGroupBase : IWorkItemsGroup 6 public abstract class WorkItemsGroupBase : IWorkItemsGroup
7 { 7 {
8 #region Private Fields 8 #region Private Fields
9 9
10 /// <summary> 10 /// <summary>
11 /// Contains the name of this instance of SmartThreadPool. 11 /// Contains the name of this instance of SmartThreadPool.
12 /// Can be changed by the user. 12 /// Can be changed by the user.
13 /// </summary> 13 /// </summary>
14 private string _name = "WorkItemsGroupBase"; 14 private string _name = "WorkItemsGroupBase";
15 15
16 public WorkItemsGroupBase() 16 public WorkItemsGroupBase()
17 { 17 {
18 IsIdle = true; 18 IsIdle = true;
19 } 19 }
20 20
21 #endregion 21 #endregion
22 22
23 #region IWorkItemsGroup Members 23 #region IWorkItemsGroup Members
24 24
25 #region Public Methods 25 #region Public Methods
26 26
27 /// <summary> 27 /// <summary>
28 /// Get/Set the name of the SmartThreadPool/WorkItemsGroup instance 28 /// Get/Set the name of the SmartThreadPool/WorkItemsGroup instance
29 /// </summary> 29 /// </summary>
30 public string Name 30 public string Name
31 { 31 {
32 get { return _name; } 32 get { return _name; }
33 set { _name = value; } 33 set { _name = value; }
34 } 34 }
35 35
36 #endregion 36 #endregion
37 37
38 #region Abstract Methods 38 #region Abstract Methods
39 39
40 public abstract int Concurrency { get; set; } 40 public abstract int Concurrency { get; set; }
41 public abstract int WaitingCallbacks { get; } 41 public abstract int WaitingCallbacks { get; }
42 public abstract object[] GetStates(); 42 public abstract object[] GetStates();
43 public abstract WIGStartInfo WIGStartInfo { get; } 43 public abstract WIGStartInfo WIGStartInfo { get; }
44 public abstract void Start(); 44 public abstract void Start();
45 public abstract void Cancel(bool abortExecution); 45 public abstract void Cancel(bool abortExecution);
46 public abstract bool WaitForIdle(int millisecondsTimeout); 46 public abstract bool WaitForIdle(int millisecondsTimeout);
47 public abstract event WorkItemsGroupIdleHandler OnIdle; 47 public abstract event WorkItemsGroupIdleHandler OnIdle;
48 48
49 internal abstract void Enqueue(WorkItem workItem); 49 internal abstract void Enqueue(WorkItem workItem);
50 internal virtual void PreQueueWorkItem() { } 50 internal virtual void PreQueueWorkItem() { }
51 51
52 #endregion 52 #endregion
53 53
54 #region Common Base Methods 54 #region Common Base Methods
55 55
56 /// <summary> 56 /// <summary>
57 /// Cancel all the work items. 57 /// Cancel all the work items.
58 /// Same as Cancel(false) 58 /// Same as Cancel(false)
59 /// </summary> 59 /// </summary>
60 public virtual void Cancel() 60 public virtual void Cancel()
61 { 61 {
62 Cancel(false); 62 Cancel(false);
63 } 63 }
64 64
65 /// <summary> 65 /// <summary>
66 /// Wait for the SmartThreadPool/WorkItemsGroup to be idle 66 /// Wait for the SmartThreadPool/WorkItemsGroup to be idle
67 /// </summary> 67 /// </summary>
68 public void WaitForIdle() 68 public void WaitForIdle()
69 { 69 {
70 WaitForIdle(Timeout.Infinite); 70 WaitForIdle(Timeout.Infinite);
71 } 71 }
72 72
73 /// <summary> 73 /// <summary>
74 /// Wait for the SmartThreadPool/WorkItemsGroup to be idle 74 /// Wait for the SmartThreadPool/WorkItemsGroup to be idle
75 /// </summary> 75 /// </summary>
76 public bool WaitForIdle(TimeSpan timeout) 76 public bool WaitForIdle(TimeSpan timeout)
77 { 77 {
78 return WaitForIdle((int)timeout.TotalMilliseconds); 78 return WaitForIdle((int)timeout.TotalMilliseconds);
79 } 79 }
80 80
81 /// <summary> 81 /// <summary>
82 /// IsIdle is true when there are no work items running or queued. 82 /// IsIdle is true when there are no work items running or queued.
83 /// </summary> 83 /// </summary>
84 public bool IsIdle { get; protected set; } 84 public bool IsIdle { get; protected set; }
85 85
86 #endregion 86 #endregion
87 87
88 #region QueueWorkItem 88 #region QueueWorkItem
89 89
90 /// <summary> 90 /// <summary>
91 /// Queue a work item 91 /// Queue a work item
92 /// </summary> 92 /// </summary>
93 /// <param name="callback">A callback to execute</param> 93 /// <param name="callback">A callback to execute</param>
94 /// <returns>Returns a work item result</returns> 94 /// <returns>Returns a work item result</returns>
95 public IWorkItemResult QueueWorkItem(WorkItemCallback callback) 95 public IWorkItemResult QueueWorkItem(WorkItemCallback callback)
96 { 96 {
97 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback); 97 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback);
98 Enqueue(workItem); 98 Enqueue(workItem);
99 return workItem.GetWorkItemResult(); 99 return workItem.GetWorkItemResult();
100 } 100 }
101 101
102 /// <summary> 102 /// <summary>
103 /// Queue a work item 103 /// Queue a work item
104 /// </summary> 104 /// </summary>
105 /// <param name="callback">A callback to execute</param> 105 /// <param name="callback">A callback to execute</param>
106 /// <param name="workItemPriority">The priority of the work item</param> 106 /// <param name="workItemPriority">The priority of the work item</param>
107 /// <returns>Returns a work item result</returns> 107 /// <returns>Returns a work item result</returns>
108 public IWorkItemResult QueueWorkItem(WorkItemCallback callback, WorkItemPriority workItemPriority) 108 public IWorkItemResult QueueWorkItem(WorkItemCallback callback, WorkItemPriority workItemPriority)
109 { 109 {
110 PreQueueWorkItem(); 110 PreQueueWorkItem();
111 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, workItemPriority); 111 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, workItemPriority);
112 Enqueue(workItem); 112 Enqueue(workItem);
113 return workItem.GetWorkItemResult(); 113 return workItem.GetWorkItemResult();
114 } 114 }
115 115
116 /// <summary> 116 /// <summary>
117 /// Queue a work item 117 /// Queue a work item
118 /// </summary> 118 /// </summary>
119 /// <param name="workItemInfo">Work item info</param> 119 /// <param name="workItemInfo">Work item info</param>
120 /// <param name="callback">A callback to execute</param> 120 /// <param name="callback">A callback to execute</param>
121 /// <returns>Returns a work item result</returns> 121 /// <returns>Returns a work item result</returns>
122 public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback) 122 public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback)
123 { 123 {
124 PreQueueWorkItem(); 124 PreQueueWorkItem();
125 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback); 125 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback);
126 Enqueue(workItem); 126 Enqueue(workItem);
127 return workItem.GetWorkItemResult(); 127 return workItem.GetWorkItemResult();
128 } 128 }
129 129
130 /// <summary> 130 /// <summary>
131 /// Queue a work item 131 /// Queue a work item
132 /// </summary> 132 /// </summary>
133 /// <param name="callback">A callback to execute</param> 133 /// <param name="callback">A callback to execute</param>
134 /// <param name="state"> 134 /// <param name="state">
135 /// The context object of the work item. Used for passing arguments to the work item. 135 /// The context object of the work item. Used for passing arguments to the work item.
136 /// </param> 136 /// </param>
137 /// <returns>Returns a work item result</returns> 137 /// <returns>Returns a work item result</returns>
138 public IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state) 138 public IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state)
139 { 139 {
140 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state); 140 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state);
141 Enqueue(workItem); 141 Enqueue(workItem);
142 return workItem.GetWorkItemResult(); 142 return workItem.GetWorkItemResult();
143 } 143 }
144 144
145 /// <summary> 145 /// <summary>
146 /// Queue a work item 146 /// Queue a work item
147 /// </summary> 147 /// </summary>
148 /// <param name="callback">A callback to execute</param> 148 /// <param name="callback">A callback to execute</param>
149 /// <param name="state"> 149 /// <param name="state">
150 /// The context object of the work item. Used for passing arguments to the work item. 150 /// The context object of the work item. Used for passing arguments to the work item.
151 /// </param> 151 /// </param>
152 /// <param name="workItemPriority">The work item priority</param> 152 /// <param name="workItemPriority">The work item priority</param>
153 /// <returns>Returns a work item result</returns> 153 /// <returns>Returns a work item result</returns>
154 public IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, WorkItemPriority workItemPriority) 154 public IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, WorkItemPriority workItemPriority)
155 { 155 {
156 PreQueueWorkItem(); 156 PreQueueWorkItem();
157 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, workItemPriority); 157 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, workItemPriority);
158 Enqueue(workItem); 158 Enqueue(workItem);
159 return workItem.GetWorkItemResult(); 159 return workItem.GetWorkItemResult();
160 } 160 }
161 161
162 /// <summary> 162 /// <summary>
163 /// Queue a work item 163 /// Queue a work item
164 /// </summary> 164 /// </summary>
165 /// <param name="workItemInfo">Work item information</param> 165 /// <param name="workItemInfo">Work item information</param>
166 /// <param name="callback">A callback to execute</param> 166 /// <param name="callback">A callback to execute</param>
167 /// <param name="state"> 167 /// <param name="state">
168 /// The context object of the work item. Used for passing arguments to the work item. 168 /// The context object of the work item. Used for passing arguments to the work item.
169 /// </param> 169 /// </param>
170 /// <returns>Returns a work item result</returns> 170 /// <returns>Returns a work item result</returns>
171 public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state) 171 public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state)
172 { 172 {
173 PreQueueWorkItem(); 173 PreQueueWorkItem();
174 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback, state); 174 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback, state);
175 Enqueue(workItem); 175 Enqueue(workItem);
176 return workItem.GetWorkItemResult(); 176 return workItem.GetWorkItemResult();
177 } 177 }
178 178
179 /// <summary> 179 /// <summary>
180 /// Queue a work item 180 /// Queue a work item
181 /// </summary> 181 /// </summary>
182 /// <param name="callback">A callback to execute</param> 182 /// <param name="callback">A callback to execute</param>
183 /// <param name="state"> 183 /// <param name="state">
184 /// The context object of the work item. Used for passing arguments to the work item. 184 /// The context object of the work item. Used for passing arguments to the work item.
185 /// </param> 185 /// </param>
186 /// <param name="postExecuteWorkItemCallback"> 186 /// <param name="postExecuteWorkItemCallback">
187 /// A delegate to call after the callback completion 187 /// A delegate to call after the callback completion
188 /// </param> 188 /// </param>
189 /// <returns>Returns a work item result</returns> 189 /// <returns>Returns a work item result</returns>
190 public IWorkItemResult QueueWorkItem( 190 public IWorkItemResult QueueWorkItem(
191 WorkItemCallback callback, 191 WorkItemCallback callback,
192 object state, 192 object state,
193 PostExecuteWorkItemCallback postExecuteWorkItemCallback) 193 PostExecuteWorkItemCallback postExecuteWorkItemCallback)
194 { 194 {
195 PreQueueWorkItem(); 195 PreQueueWorkItem();
196 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback); 196 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback);
197 Enqueue(workItem); 197 Enqueue(workItem);
198 return workItem.GetWorkItemResult(); 198 return workItem.GetWorkItemResult();
199 } 199 }
200 200
201 /// <summary> 201 /// <summary>
202 /// Queue a work item 202 /// Queue a work item
203 /// </summary> 203 /// </summary>
204 /// <param name="callback">A callback to execute</param> 204 /// <param name="callback">A callback to execute</param>
205 /// <param name="state"> 205 /// <param name="state">
206 /// The context object of the work item. Used for passing arguments to the work item. 206 /// The context object of the work item. Used for passing arguments to the work item.
207 /// </param> 207 /// </param>
208 /// <param name="postExecuteWorkItemCallback"> 208 /// <param name="postExecuteWorkItemCallback">
209 /// A delegate to call after the callback completion 209 /// A delegate to call after the callback completion
210 /// </param> 210 /// </param>
211 /// <param name="workItemPriority">The work item priority</param> 211 /// <param name="workItemPriority">The work item priority</param>
212 /// <returns>Returns a work item result</returns> 212 /// <returns>Returns a work item result</returns>
213 public IWorkItemResult QueueWorkItem( 213 public IWorkItemResult QueueWorkItem(
214 WorkItemCallback callback, 214 WorkItemCallback callback,
215 object state, 215 object state,
216 PostExecuteWorkItemCallback postExecuteWorkItemCallback, 216 PostExecuteWorkItemCallback postExecuteWorkItemCallback,
217 WorkItemPriority workItemPriority) 217 WorkItemPriority workItemPriority)
218 { 218 {
219 PreQueueWorkItem(); 219 PreQueueWorkItem();
220 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, workItemPriority); 220 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, workItemPriority);
221 Enqueue(workItem); 221 Enqueue(workItem);
222 return workItem.GetWorkItemResult(); 222 return workItem.GetWorkItemResult();
223 } 223 }
224 224
225 /// <summary> 225 /// <summary>
226 /// Queue a work item 226 /// Queue a work item
227 /// </summary> 227 /// </summary>
228 /// <param name="callback">A callback to execute</param> 228 /// <param name="callback">A callback to execute</param>
229 /// <param name="state"> 229 /// <param name="state">
230 /// The context object of the work item. Used for passing arguments to the work item. 230 /// The context object of the work item. Used for passing arguments to the work item.
231 /// </param> 231 /// </param>
232 /// <param name="postExecuteWorkItemCallback"> 232 /// <param name="postExecuteWorkItemCallback">
233 /// A delegate to call after the callback completion 233 /// A delegate to call after the callback completion
234 /// </param> 234 /// </param>
235 /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param> 235 /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
236 /// <returns>Returns a work item result</returns> 236 /// <returns>Returns a work item result</returns>
237 public IWorkItemResult QueueWorkItem( 237 public IWorkItemResult QueueWorkItem(
238 WorkItemCallback callback, 238 WorkItemCallback callback,
239 object state, 239 object state,
240 PostExecuteWorkItemCallback postExecuteWorkItemCallback, 240 PostExecuteWorkItemCallback postExecuteWorkItemCallback,
241 CallToPostExecute callToPostExecute) 241 CallToPostExecute callToPostExecute)
242 { 242 {
243 PreQueueWorkItem(); 243 PreQueueWorkItem();
244 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute); 244 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute);
245 Enqueue(workItem); 245 Enqueue(workItem);
246 return workItem.GetWorkItemResult(); 246 return workItem.GetWorkItemResult();
247 } 247 }
248 248
249 /// <summary> 249 /// <summary>
250 /// Queue a work item 250 /// Queue a work item
251 /// </summary> 251 /// </summary>
252 /// <param name="callback">A callback to execute</param> 252 /// <param name="callback">A callback to execute</param>
253 /// <param name="state"> 253 /// <param name="state">
254 /// The context object of the work item. Used for passing arguments to the work item. 254 /// The context object of the work item. Used for passing arguments to the work item.
255 /// </param> 255 /// </param>
256 /// <param name="postExecuteWorkItemCallback"> 256 /// <param name="postExecuteWorkItemCallback">
257 /// A delegate to call after the callback completion 257 /// A delegate to call after the callback completion
258 /// </param> 258 /// </param>
259 /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param> 259 /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
260 /// <param name="workItemPriority">The work item priority</param> 260 /// <param name="workItemPriority">The work item priority</param>
261 /// <returns>Returns a work item result</returns> 261 /// <returns>Returns a work item result</returns>
262 public IWorkItemResult QueueWorkItem( 262 public IWorkItemResult QueueWorkItem(
263 WorkItemCallback callback, 263 WorkItemCallback callback,
264 object state, 264 object state,
265 PostExecuteWorkItemCallback postExecuteWorkItemCallback, 265 PostExecuteWorkItemCallback postExecuteWorkItemCallback,
266 CallToPostExecute callToPostExecute, 266 CallToPostExecute callToPostExecute,
267 WorkItemPriority workItemPriority) 267 WorkItemPriority workItemPriority)
268 { 268 {
269 PreQueueWorkItem(); 269 PreQueueWorkItem();
270 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute, workItemPriority); 270 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute, workItemPriority);
271 Enqueue(workItem); 271 Enqueue(workItem);
272 return workItem.GetWorkItemResult(); 272 return workItem.GetWorkItemResult();
273 } 273 }
274 274
275 #endregion 275 #endregion
276 276
277 #region QueueWorkItem(Action<...>) 277 #region QueueWorkItem(Action<...>)
278 278
279 public IWorkItemResult QueueWorkItem(Action action) 279 public IWorkItemResult QueueWorkItem(Action action)
280 { 280 {
281 return QueueWorkItem (action, SmartThreadPool.DefaultWorkItemPriority); 281 return QueueWorkItem (action, SmartThreadPool.DefaultWorkItemPriority);
282 } 282 }
283 283
284 public IWorkItemResult QueueWorkItem (Action action, WorkItemPriority priority) 284 public IWorkItemResult QueueWorkItem (Action action, WorkItemPriority priority)
285 { 285 {
286 PreQueueWorkItem (); 286 PreQueueWorkItem ();
287 WorkItem workItem = WorkItemFactory.CreateWorkItem ( 287 WorkItem workItem = WorkItemFactory.CreateWorkItem (
288 this, 288 this,
289 WIGStartInfo, 289 WIGStartInfo,
290 delegate 290 delegate
291 { 291 {
292 action.Invoke (); 292 action.Invoke ();
293 return null; 293 return null;
294 }, priority); 294 }, priority);
295 Enqueue (workItem); 295 Enqueue (workItem);
296 return workItem.GetWorkItemResult (); 296 return workItem.GetWorkItemResult ();
297 } 297 }
298 298
299 public IWorkItemResult QueueWorkItem<T>(Action<T> action, T arg) 299 public IWorkItemResult QueueWorkItem<T>(Action<T> action, T arg)
300 { 300 {
301 return QueueWorkItem<T> (action, arg, SmartThreadPool.DefaultWorkItemPriority); 301 return QueueWorkItem<T> (action, arg, SmartThreadPool.DefaultWorkItemPriority);
302 } 302 }
303 303
304 public IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg, WorkItemPriority priority) 304 public IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg, WorkItemPriority priority)
305 { 305 {
306 PreQueueWorkItem (); 306 PreQueueWorkItem ();
307 WorkItem workItem = WorkItemFactory.CreateWorkItem ( 307 WorkItem workItem = WorkItemFactory.CreateWorkItem (
308 this, 308 this,
309 WIGStartInfo, 309 WIGStartInfo,
310 state => 310 state =>
311 { 311 {
312 action.Invoke (arg); 312 action.Invoke (arg);
313 return null; 313 return null;
314 }, 314 },
315 WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null, priority); 315 WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null, priority);
316 Enqueue (workItem); 316 Enqueue (workItem);
317 return workItem.GetWorkItemResult (); 317 return workItem.GetWorkItemResult ();
318 } 318 }
319 319
320 public IWorkItemResult QueueWorkItem<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2) 320 public IWorkItemResult QueueWorkItem<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2)
321 { 321 {
322 return QueueWorkItem<T1, T2> (action, arg1, arg2, SmartThreadPool.DefaultWorkItemPriority); 322 return QueueWorkItem<T1, T2> (action, arg1, arg2, SmartThreadPool.DefaultWorkItemPriority);
323 } 323 }
324 324
325 public IWorkItemResult QueueWorkItem<T1, T2> (Action<T1, T2> action, T1 arg1, T2 arg2, WorkItemPriority priority) 325 public IWorkItemResult QueueWorkItem<T1, T2> (Action<T1, T2> action, T1 arg1, T2 arg2, WorkItemPriority priority)
326 { 326 {
327 PreQueueWorkItem (); 327 PreQueueWorkItem ();
328 WorkItem workItem = WorkItemFactory.CreateWorkItem ( 328 WorkItem workItem = WorkItemFactory.CreateWorkItem (
329 this, 329 this,
330 WIGStartInfo, 330 WIGStartInfo,
331 state => 331 state =>
332 { 332 {
333 action.Invoke (arg1, arg2); 333 action.Invoke (arg1, arg2);
334 return null; 334 return null;
335 }, 335 },
336 WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null, priority); 336 WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null, priority);
337 Enqueue (workItem); 337 Enqueue (workItem);
338 return workItem.GetWorkItemResult (); 338 return workItem.GetWorkItemResult ();
339 } 339 }
340 340
341 public IWorkItemResult QueueWorkItem<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3) 341 public IWorkItemResult QueueWorkItem<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3)
342 { 342 {
343 return QueueWorkItem<T1, T2, T3> (action, arg1, arg2, arg3, SmartThreadPool.DefaultWorkItemPriority); 343 return QueueWorkItem<T1, T2, T3> (action, arg1, arg2, arg3, SmartThreadPool.DefaultWorkItemPriority);
344 ; 344 ;
345 } 345 }
346 346
347 public IWorkItemResult QueueWorkItem<T1, T2, T3> (Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3, WorkItemPriority priority) 347 public IWorkItemResult QueueWorkItem<T1, T2, T3> (Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3, WorkItemPriority priority)
348 { 348 {
349 PreQueueWorkItem (); 349 PreQueueWorkItem ();
350 WorkItem workItem = WorkItemFactory.CreateWorkItem ( 350 WorkItem workItem = WorkItemFactory.CreateWorkItem (
351 this, 351 this,
352 WIGStartInfo, 352 WIGStartInfo,
353 state => 353 state =>
354 { 354 {
355 action.Invoke (arg1, arg2, arg3); 355 action.Invoke (arg1, arg2, arg3);
356 return null; 356 return null;
357 }, 357 },
358 WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null, priority); 358 WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null, priority);
359 Enqueue (workItem); 359 Enqueue (workItem);
360 return workItem.GetWorkItemResult (); 360 return workItem.GetWorkItemResult ();
361 } 361 }
362 362
363 public IWorkItemResult QueueWorkItem<T1, T2, T3, T4>( 363 public IWorkItemResult QueueWorkItem<T1, T2, T3, T4>(
364 Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4) 364 Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
365 { 365 {
366 return QueueWorkItem<T1, T2, T3, T4> (action, arg1, arg2, arg3, arg4, 366 return QueueWorkItem<T1, T2, T3, T4> (action, arg1, arg2, arg3, arg4,
367 SmartThreadPool.DefaultWorkItemPriority); 367 SmartThreadPool.DefaultWorkItemPriority);
368 } 368 }
369 369
370 public IWorkItemResult QueueWorkItem<T1, T2, T3, T4> ( 370 public IWorkItemResult QueueWorkItem<T1, T2, T3, T4> (
371 Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, WorkItemPriority priority) 371 Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, WorkItemPriority priority)
372 { 372 {
373 PreQueueWorkItem (); 373 PreQueueWorkItem ();
374 WorkItem workItem = WorkItemFactory.CreateWorkItem ( 374 WorkItem workItem = WorkItemFactory.CreateWorkItem (
375 this, 375 this,
376 WIGStartInfo, 376 WIGStartInfo,
377 state => 377 state =>
378 { 378 {
379 action.Invoke (arg1, arg2, arg3, arg4); 379 action.Invoke (arg1, arg2, arg3, arg4);
380 return null; 380 return null;
381 }, 381 },
382 WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null, priority); 382 WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null, priority);
383 Enqueue (workItem); 383 Enqueue (workItem);
384 return workItem.GetWorkItemResult (); 384 return workItem.GetWorkItemResult ();
385 } 385 }
386 386
387 #endregion 387 #endregion
388 388
389 #region QueueWorkItem(Func<...>) 389 #region QueueWorkItem(Func<...>)
390 390
391 public IWorkItemResult<TResult> QueueWorkItem<TResult>(Func<TResult> func) 391 public IWorkItemResult<TResult> QueueWorkItem<TResult>(Func<TResult> func)
392 { 392 {
393 PreQueueWorkItem(); 393 PreQueueWorkItem();
394 WorkItem workItem = WorkItemFactory.CreateWorkItem( 394 WorkItem workItem = WorkItemFactory.CreateWorkItem(
395 this, 395 this,
396 WIGStartInfo, 396 WIGStartInfo,
397 state => 397 state =>
398 { 398 {
399 return func.Invoke(); 399 return func.Invoke();
400 }); 400 });
401 Enqueue(workItem); 401 Enqueue(workItem);
402 return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult()); 402 return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
403 } 403 }
404 404
405 public IWorkItemResult<TResult> QueueWorkItem<T, TResult>(Func<T, TResult> func, T arg) 405 public IWorkItemResult<TResult> QueueWorkItem<T, TResult>(Func<T, TResult> func, T arg)
406 { 406 {
407 PreQueueWorkItem(); 407 PreQueueWorkItem();
408 WorkItem workItem = WorkItemFactory.CreateWorkItem( 408 WorkItem workItem = WorkItemFactory.CreateWorkItem(
409 this, 409 this,
410 WIGStartInfo, 410 WIGStartInfo,
411 state => 411 state =>
412 { 412 {
413 return func.Invoke(arg); 413 return func.Invoke(arg);
414 }, 414 },
415 WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null); 415 WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null);
416 Enqueue(workItem); 416 Enqueue(workItem);
417 return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult()); 417 return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
418 } 418 }
419 419
420 public IWorkItemResult<TResult> QueueWorkItem<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 arg1, T2 arg2) 420 public IWorkItemResult<TResult> QueueWorkItem<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 arg1, T2 arg2)
421 { 421 {
422 PreQueueWorkItem(); 422 PreQueueWorkItem();
423 WorkItem workItem = WorkItemFactory.CreateWorkItem( 423 WorkItem workItem = WorkItemFactory.CreateWorkItem(
424 this, 424 this,
425 WIGStartInfo, 425 WIGStartInfo,
426 state => 426 state =>
427 { 427 {
428 return func.Invoke(arg1, arg2); 428 return func.Invoke(arg1, arg2);
429 }, 429 },
430 WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null); 430 WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null);
431 Enqueue(workItem); 431 Enqueue(workItem);
432 return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult()); 432 return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
433 } 433 }
434 434
435 public IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, TResult>( 435 public IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, TResult>(
436 Func<T1, T2, T3, TResult> func, T1 arg1, T2 arg2, T3 arg3) 436 Func<T1, T2, T3, TResult> func, T1 arg1, T2 arg2, T3 arg3)
437 { 437 {
438 PreQueueWorkItem(); 438 PreQueueWorkItem();
439 WorkItem workItem = WorkItemFactory.CreateWorkItem( 439 WorkItem workItem = WorkItemFactory.CreateWorkItem(
440 this, 440 this,
441 WIGStartInfo, 441 WIGStartInfo,
442 state => 442 state =>
443 { 443 {
444 return func.Invoke(arg1, arg2, arg3); 444 return func.Invoke(arg1, arg2, arg3);
445 }, 445 },
446 WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null); 446 WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null);
447 Enqueue(workItem); 447 Enqueue(workItem);
448 return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult()); 448 return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
449 } 449 }
450 450
451 public IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, T4, TResult>( 451 public IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, T4, TResult>(
452 Func<T1, T2, T3, T4, TResult> func, T1 arg1, T2 arg2, T3 arg3, T4 arg4) 452 Func<T1, T2, T3, T4, TResult> func, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
453 { 453 {
454 PreQueueWorkItem(); 454 PreQueueWorkItem();
455 WorkItem workItem = WorkItemFactory.CreateWorkItem( 455 WorkItem workItem = WorkItemFactory.CreateWorkItem(
456 this, 456 this,
457 WIGStartInfo, 457 WIGStartInfo,
458 state => 458 state =>
459 { 459 {
460 return func.Invoke(arg1, arg2, arg3, arg4); 460 return func.Invoke(arg1, arg2, arg3, arg4);
461 }, 461 },
462 WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null); 462 WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null);
463 Enqueue(workItem); 463 Enqueue(workItem);
464 return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult()); 464 return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
465 } 465 }
466 466
467 #endregion 467 #endregion
468 468
469 #endregion 469 #endregion
470 } 470 }
471} \ No newline at end of file 471} \ No newline at end of file
diff --git a/ThirdParty/SmartThreadPool/WorkItemsQueue.cs b/ThirdParty/SmartThreadPool/WorkItemsQueue.cs
index 156a131..e0bc916 100644
--- a/ThirdParty/SmartThreadPool/WorkItemsQueue.cs
+++ b/ThirdParty/SmartThreadPool/WorkItemsQueue.cs
@@ -1,645 +1,645 @@
1using System; 1using System;
2using System.Collections.Generic; 2using System.Collections.Generic;
3using System.Threading; 3using System.Threading;
4 4
5namespace Amib.Threading.Internal 5namespace Amib.Threading.Internal
6{ 6{
7 #region WorkItemsQueue class 7 #region WorkItemsQueue class
8 8
9 /// <summary> 9 /// <summary>
10 /// WorkItemsQueue class. 10 /// WorkItemsQueue class.
11 /// </summary> 11 /// </summary>
12 public class WorkItemsQueue : IDisposable 12 public class WorkItemsQueue : IDisposable
13 { 13 {
14 #region Member variables 14 #region Member variables
15 15
16 /// <summary> 16 /// <summary>
17 /// Waiters queue (implemented as stack). 17 /// Waiters queue (implemented as stack).
18 /// </summary> 18 /// </summary>
19 private readonly WaiterEntry _headWaiterEntry = new WaiterEntry(); 19 private readonly WaiterEntry _headWaiterEntry = new WaiterEntry();
20 20
21 /// <summary> 21 /// <summary>
22 /// Waiters count 22 /// Waiters count
23 /// </summary> 23 /// </summary>
24 private int _waitersCount = 0; 24 private int _waitersCount = 0;
25 25
26 /// <summary> 26 /// <summary>
27 /// Work items queue 27 /// Work items queue
28 /// </summary> 28 /// </summary>
29 private readonly PriorityQueue _workItems = new PriorityQueue(); 29 private readonly PriorityQueue _workItems = new PriorityQueue();
30 30
31 /// <summary> 31 /// <summary>
32 /// Indicate that work items are allowed to be queued 32 /// Indicate that work items are allowed to be queued
33 /// </summary> 33 /// </summary>
34 private bool _isWorkItemsQueueActive = true; 34 private bool _isWorkItemsQueueActive = true;
35 35
36 36
37#if (WINDOWS_PHONE) 37#if (WINDOWS_PHONE)
38 private static readonly Dictionary<int, WaiterEntry> _waiterEntries = new Dictionary<int, WaiterEntry>(); 38 private static readonly Dictionary<int, WaiterEntry> _waiterEntries = new Dictionary<int, WaiterEntry>();
39#elif (_WINDOWS_CE) 39#elif (_WINDOWS_CE)
40 private static LocalDataStoreSlot _waiterEntrySlot = Thread.AllocateDataSlot(); 40 private static LocalDataStoreSlot _waiterEntrySlot = Thread.AllocateDataSlot();
41#else 41#else
42 42
43 [ThreadStatic] 43 [ThreadStatic]
44 private static WaiterEntry _waiterEntry; 44 private static WaiterEntry _waiterEntry;
45#endif 45#endif
46 46
47 47
48 /// <summary> 48 /// <summary>
49 /// Each thread in the thread pool keeps its own waiter entry. 49 /// Each thread in the thread pool keeps its own waiter entry.
50 /// </summary> 50 /// </summary>
51 private static WaiterEntry CurrentWaiterEntry 51 private static WaiterEntry CurrentWaiterEntry
52 { 52 {
53#if (WINDOWS_PHONE) 53#if (WINDOWS_PHONE)
54 get 54 get
55 { 55 {
56 lock (_waiterEntries) 56 lock (_waiterEntries)
57 { 57 {
58 WaiterEntry waiterEntry; 58 WaiterEntry waiterEntry;
59 if (_waiterEntries.TryGetValue(Thread.CurrentThread.ManagedThreadId, out waiterEntry)) 59 if (_waiterEntries.TryGetValue(Thread.CurrentThread.ManagedThreadId, out waiterEntry))
60 { 60 {
61 return waiterEntry; 61 return waiterEntry;
62 } 62 }
63 } 63 }
64 return null; 64 return null;
65 } 65 }
66 set 66 set
67 { 67 {
68 lock (_waiterEntries) 68 lock (_waiterEntries)
69 { 69 {
70 _waiterEntries[Thread.CurrentThread.ManagedThreadId] = value; 70 _waiterEntries[Thread.CurrentThread.ManagedThreadId] = value;
71 } 71 }
72 } 72 }
73#elif (_WINDOWS_CE) 73#elif (_WINDOWS_CE)
74 get 74 get
75 { 75 {
76 return Thread.GetData(_waiterEntrySlot) as WaiterEntry; 76 return Thread.GetData(_waiterEntrySlot) as WaiterEntry;
77 } 77 }
78 set 78 set
79 { 79 {
80 Thread.SetData(_waiterEntrySlot, value); 80 Thread.SetData(_waiterEntrySlot, value);
81 } 81 }
82#else 82#else
83 get 83 get
84 { 84 {
85 return _waiterEntry; 85 return _waiterEntry;
86 } 86 }
87 set 87 set
88 { 88 {
89 _waiterEntry = value; 89 _waiterEntry = value;
90 } 90 }
91#endif 91#endif
92 } 92 }
93 93
94 /// <summary> 94 /// <summary>
95 /// A flag that indicates if the WorkItemsQueue has been disposed. 95 /// A flag that indicates if the WorkItemsQueue has been disposed.
96 /// </summary> 96 /// </summary>
97 private bool _isDisposed = false; 97 private bool _isDisposed = false;
98 98
99 #endregion 99 #endregion
100 100
101 #region Public properties 101 #region Public properties
102 102
103 /// <summary> 103 /// <summary>
104 /// Returns the current number of work items in the queue 104 /// Returns the current number of work items in the queue
105 /// </summary> 105 /// </summary>
106 public int Count 106 public int Count
107 { 107 {
108 get 108 get
109 { 109 {
110 return _workItems.Count; 110 return _workItems.Count;
111 } 111 }
112 } 112 }
113 113
114 /// <summary> 114 /// <summary>
115 /// Returns the current number of waiters 115 /// Returns the current number of waiters
116 /// </summary> 116 /// </summary>
117 public int WaitersCount 117 public int WaitersCount
118 { 118 {
119 get 119 get
120 { 120 {
121 return _waitersCount; 121 return _waitersCount;
122 } 122 }
123 } 123 }
124 124
125 125
126 #endregion 126 #endregion
127 127
128 #region Public methods 128 #region Public methods
129 129
130 /// <summary> 130 /// <summary>
131 /// Enqueue a work item to the queue. 131 /// Enqueue a work item to the queue.
132 /// </summary> 132 /// </summary>
133 public bool EnqueueWorkItem(WorkItem workItem) 133 public bool EnqueueWorkItem(WorkItem workItem)
134 { 134 {
135 // A work item cannot be null, since null is used in the 135 // A work item cannot be null, since null is used in the
136 // WaitForWorkItem() method to indicate timeout or cancel 136 // WaitForWorkItem() method to indicate timeout or cancel
137 if (null == workItem) 137 if (null == workItem)
138 { 138 {
139 throw new ArgumentNullException("workItem" , "workItem cannot be null"); 139 throw new ArgumentNullException("workItem" , "workItem cannot be null");
140 } 140 }
141 141
142 bool enqueue = true; 142 bool enqueue = true;
143 143
144 // First check if there is a waiter waiting for work item. During 144 // First check if there is a waiter waiting for work item. During
145 // the check, timed out waiters are ignored. If there is no 145 // the check, timed out waiters are ignored. If there is no
146 // waiter then the work item is queued. 146 // waiter then the work item is queued.
147 lock(this) 147 lock(this)
148 { 148 {
149 ValidateNotDisposed(); 149 ValidateNotDisposed();
150 150
151 if (!_isWorkItemsQueueActive) 151 if (!_isWorkItemsQueueActive)
152 { 152 {
153 return false; 153 return false;
154 } 154 }
155 155
156 while(_waitersCount > 0) 156 while(_waitersCount > 0)
157 { 157 {
158 // Dequeue a waiter. 158 // Dequeue a waiter.
159 WaiterEntry waiterEntry = PopWaiter(); 159 WaiterEntry waiterEntry = PopWaiter();
160 160
161 // Signal the waiter. On success break the loop 161 // Signal the waiter. On success break the loop
162 if (waiterEntry.Signal(workItem)) 162 if (waiterEntry.Signal(workItem))
163 { 163 {
164 enqueue = false; 164 enqueue = false;
165 break; 165 break;
166 } 166 }
167 } 167 }
168 168
169 if (enqueue) 169 if (enqueue)
170 { 170 {
171 // Enqueue the work item 171 // Enqueue the work item
172 _workItems.Enqueue(workItem); 172 _workItems.Enqueue(workItem);
173 } 173 }
174 } 174 }
175 return true; 175 return true;
176 } 176 }
177 177
178 178
179 /// <summary> 179 /// <summary>
180 /// Waits for a work item or exits on timeout or cancel 180 /// Waits for a work item or exits on timeout or cancel
181 /// </summary> 181 /// </summary>
182 /// <param name="millisecondsTimeout">Timeout in milliseconds</param> 182 /// <param name="millisecondsTimeout">Timeout in milliseconds</param>
183 /// <param name="cancelEvent">Cancel wait handle</param> 183 /// <param name="cancelEvent">Cancel wait handle</param>
184 /// <returns>Returns true if the resource was granted</returns> 184 /// <returns>Returns true if the resource was granted</returns>
185 public WorkItem DequeueWorkItem( 185 public WorkItem DequeueWorkItem(
186 int millisecondsTimeout, 186 int millisecondsTimeout,
187 WaitHandle cancelEvent) 187 WaitHandle cancelEvent)
188 { 188 {
189 // This method cause the caller to wait for a work item. 189 // This method cause the caller to wait for a work item.
190 // If there is at least one waiting work item then the 190 // If there is at least one waiting work item then the
191 // method returns immidiately with it. 191 // method returns immidiately with it.
192 // 192 //
193 // If there are no waiting work items then the caller 193 // If there are no waiting work items then the caller
194 // is queued between other waiters for a work item to arrive. 194 // is queued between other waiters for a work item to arrive.
195 // 195 //
196 // If a work item didn't come within millisecondsTimeout or 196 // If a work item didn't come within millisecondsTimeout or
197 // the user canceled the wait by signaling the cancelEvent 197 // the user canceled the wait by signaling the cancelEvent
198 // then the method returns null to indicate that the caller 198 // then the method returns null to indicate that the caller
199 // didn't get a work item. 199 // didn't get a work item.
200 200
201 WaiterEntry waiterEntry; 201 WaiterEntry waiterEntry;
202 WorkItem workItem = null; 202 WorkItem workItem = null;
203 lock (this) 203 lock (this)
204 { 204 {
205 ValidateNotDisposed(); 205 ValidateNotDisposed();
206 206
207 // If there are waiting work items then take one and return. 207 // If there are waiting work items then take one and return.
208 if (_workItems.Count > 0) 208 if (_workItems.Count > 0)
209 { 209 {
210 workItem = _workItems.Dequeue() as WorkItem; 210 workItem = _workItems.Dequeue() as WorkItem;
211 return workItem; 211 return workItem;
212 } 212 }
213 213
214 // No waiting work items ... 214 // No waiting work items ...
215 215
216 // Get the waiter entry for the waiters queue 216 // Get the waiter entry for the waiters queue
217 waiterEntry = GetThreadWaiterEntry(); 217 waiterEntry = GetThreadWaiterEntry();
218 218
219 // Put the waiter with the other waiters 219 // Put the waiter with the other waiters
220 PushWaiter(waiterEntry); 220 PushWaiter(waiterEntry);
221 } 221 }
222 222
223 // Prepare array of wait handle for the WaitHandle.WaitAny() 223 // Prepare array of wait handle for the WaitHandle.WaitAny()
224 WaitHandle [] waitHandles = new WaitHandle[] { 224 WaitHandle [] waitHandles = new WaitHandle[] {
225 waiterEntry.WaitHandle, 225 waiterEntry.WaitHandle,
226 cancelEvent }; 226 cancelEvent };
227 227
228 // Wait for an available resource, cancel event, or timeout. 228 // Wait for an available resource, cancel event, or timeout.
229 229
230 // During the wait we are supposes to exit the synchronization 230 // During the wait we are supposes to exit the synchronization
231 // domain. (Placing true as the third argument of the WaitAny()) 231 // domain. (Placing true as the third argument of the WaitAny())
232 // It just doesn't work, I don't know why, so I have two lock(this) 232 // It just doesn't work, I don't know why, so I have two lock(this)
233 // statments instead of one. 233 // statments instead of one.
234 234
235 int index = STPEventWaitHandle.WaitAny( 235 int index = STPEventWaitHandle.WaitAny(
236 waitHandles, 236 waitHandles,
237 millisecondsTimeout, 237 millisecondsTimeout,
238 true); 238 true);
239 239
240 lock(this) 240 lock(this)
241 { 241 {
242 // success is true if it got a work item. 242 // success is true if it got a work item.
243 bool success = (0 == index); 243 bool success = (0 == index);
244 244
245 // The timeout variable is used only for readability. 245 // The timeout variable is used only for readability.
246 // (We treat cancel as timeout) 246 // (We treat cancel as timeout)
247 bool timeout = !success; 247 bool timeout = !success;
248 248
249 // On timeout update the waiterEntry that it is timed out 249 // On timeout update the waiterEntry that it is timed out
250 if (timeout) 250 if (timeout)
251 { 251 {
252 // The Timeout() fails if the waiter has already been signaled 252 // The Timeout() fails if the waiter has already been signaled
253 timeout = waiterEntry.Timeout(); 253 timeout = waiterEntry.Timeout();
254 254
255 // On timeout remove the waiter from the queue. 255 // On timeout remove the waiter from the queue.
256 // Note that the complexity is O(1). 256 // Note that the complexity is O(1).
257 if(timeout) 257 if(timeout)
258 { 258 {
259 RemoveWaiter(waiterEntry, false); 259 RemoveWaiter(waiterEntry, false);
260 } 260 }
261 261
262 // Again readability 262 // Again readability
263 success = !timeout; 263 success = !timeout;
264 } 264 }
265 265
266 // On success return the work item 266 // On success return the work item
267 if (success) 267 if (success)
268 { 268 {
269 workItem = waiterEntry.WorkItem; 269 workItem = waiterEntry.WorkItem;
270 270
271 if (null == workItem) 271 if (null == workItem)
272 { 272 {
273 workItem = _workItems.Dequeue() as WorkItem; 273 workItem = _workItems.Dequeue() as WorkItem;
274 } 274 }
275 } 275 }
276 } 276 }
277 // On failure return null. 277 // On failure return null.
278 return workItem; 278 return workItem;
279 } 279 }
280 280
281 /// <summary> 281 /// <summary>
282 /// Cleanup the work items queue, hence no more work 282 /// Cleanup the work items queue, hence no more work
283 /// items are allowed to be queue 283 /// items are allowed to be queue
284 /// </summary> 284 /// </summary>
285 private void Cleanup() 285 private void Cleanup()
286 { 286 {
287 lock(this) 287 lock(this)
288 { 288 {
289 // Deactivate only once 289 // Deactivate only once
290 if (!_isWorkItemsQueueActive) 290 if (!_isWorkItemsQueueActive)
291 { 291 {
292 return; 292 return;
293 } 293 }
294 294
295 // Don't queue more work items 295 // Don't queue more work items
296 _isWorkItemsQueueActive = false; 296 _isWorkItemsQueueActive = false;
297 297
298 foreach(WorkItem workItem in _workItems) 298 foreach(WorkItem workItem in _workItems)
299 { 299 {
300 workItem.DisposeOfState(); 300 workItem.DisposeOfState();
301 } 301 }
302 302
303 // Clear the work items that are already queued 303 // Clear the work items that are already queued
304 _workItems.Clear(); 304 _workItems.Clear();
305 305
306 // Note: 306 // Note:
307 // I don't iterate over the queue and dispose of work items's states, 307 // I don't iterate over the queue and dispose of work items's states,
308 // since if a work item has a state object that is still in use in the 308 // since if a work item has a state object that is still in use in the
309 // application then I must not dispose it. 309 // application then I must not dispose it.
310 310
311 // Tell the waiters that they were timed out. 311 // Tell the waiters that they were timed out.
312 // It won't signal them to exit, but to ignore their 312 // It won't signal them to exit, but to ignore their
313 // next work item. 313 // next work item.
314 while(_waitersCount > 0) 314 while(_waitersCount > 0)
315 { 315 {
316 WaiterEntry waiterEntry = PopWaiter(); 316 WaiterEntry waiterEntry = PopWaiter();
317 waiterEntry.Timeout(); 317 waiterEntry.Timeout();
318 } 318 }
319 } 319 }
320 } 320 }
321 321
322 public object[] GetStates() 322 public object[] GetStates()
323 { 323 {
324 lock (this) 324 lock (this)
325 { 325 {
326 object[] states = new object[_workItems.Count]; 326 object[] states = new object[_workItems.Count];
327 int i = 0; 327 int i = 0;
328 foreach (WorkItem workItem in _workItems) 328 foreach (WorkItem workItem in _workItems)
329 { 329 {
330 states[i] = workItem.GetWorkItemResult().State; 330 states[i] = workItem.GetWorkItemResult().State;
331 ++i; 331 ++i;
332 } 332 }
333 return states; 333 return states;
334 } 334 }
335 } 335 }
336 336
337 #endregion 337 #endregion
338 338
339 #region Private methods 339 #region Private methods
340 340
341 /// <summary> 341 /// <summary>
342 /// Returns the WaiterEntry of the current thread 342 /// Returns the WaiterEntry of the current thread
343 /// </summary> 343 /// </summary>
344 /// <returns></returns> 344 /// <returns></returns>
345 /// In order to avoid creation and destuction of WaiterEntry 345 /// In order to avoid creation and destuction of WaiterEntry
346 /// objects each thread has its own WaiterEntry object. 346 /// objects each thread has its own WaiterEntry object.
347 private static WaiterEntry GetThreadWaiterEntry() 347 private static WaiterEntry GetThreadWaiterEntry()
348 { 348 {
349 if (null == CurrentWaiterEntry) 349 if (null == CurrentWaiterEntry)
350 { 350 {
351 CurrentWaiterEntry = new WaiterEntry(); 351 CurrentWaiterEntry = new WaiterEntry();
352 } 352 }
353 CurrentWaiterEntry.Reset(); 353 CurrentWaiterEntry.Reset();
354 return CurrentWaiterEntry; 354 return CurrentWaiterEntry;
355 } 355 }
356 356
357 #region Waiters stack methods 357 #region Waiters stack methods
358 358
359 /// <summary> 359 /// <summary>
360 /// Push a new waiter into the waiter's stack 360 /// Push a new waiter into the waiter's stack
361 /// </summary> 361 /// </summary>
362 /// <param name="newWaiterEntry">A waiter to put in the stack</param> 362 /// <param name="newWaiterEntry">A waiter to put in the stack</param>
363 public void PushWaiter(WaiterEntry newWaiterEntry) 363 public void PushWaiter(WaiterEntry newWaiterEntry)
364 { 364 {
365 // Remove the waiter if it is already in the stack and 365 // Remove the waiter if it is already in the stack and
366 // update waiter's count as needed 366 // update waiter's count as needed
367 RemoveWaiter(newWaiterEntry, false); 367 RemoveWaiter(newWaiterEntry, false);
368 368
369 // If the stack is empty then newWaiterEntry is the new head of the stack 369 // If the stack is empty then newWaiterEntry is the new head of the stack
370 if (null == _headWaiterEntry._nextWaiterEntry) 370 if (null == _headWaiterEntry._nextWaiterEntry)
371 { 371 {
372 _headWaiterEntry._nextWaiterEntry = newWaiterEntry; 372 _headWaiterEntry._nextWaiterEntry = newWaiterEntry;
373 newWaiterEntry._prevWaiterEntry = _headWaiterEntry; 373 newWaiterEntry._prevWaiterEntry = _headWaiterEntry;
374 374
375 } 375 }
376 // If the stack is not empty then put newWaiterEntry as the new head 376 // If the stack is not empty then put newWaiterEntry as the new head
377 // of the stack. 377 // of the stack.
378 else 378 else
379 { 379 {
380 // Save the old first waiter entry 380 // Save the old first waiter entry
381 WaiterEntry oldFirstWaiterEntry = _headWaiterEntry._nextWaiterEntry; 381 WaiterEntry oldFirstWaiterEntry = _headWaiterEntry._nextWaiterEntry;
382 382
383 // Update the links 383 // Update the links
384 _headWaiterEntry._nextWaiterEntry = newWaiterEntry; 384 _headWaiterEntry._nextWaiterEntry = newWaiterEntry;
385 newWaiterEntry._nextWaiterEntry = oldFirstWaiterEntry; 385 newWaiterEntry._nextWaiterEntry = oldFirstWaiterEntry;
386 newWaiterEntry._prevWaiterEntry = _headWaiterEntry; 386 newWaiterEntry._prevWaiterEntry = _headWaiterEntry;
387 oldFirstWaiterEntry._prevWaiterEntry = newWaiterEntry; 387 oldFirstWaiterEntry._prevWaiterEntry = newWaiterEntry;
388 } 388 }
389 389
390 // Increment the number of waiters 390 // Increment the number of waiters
391 ++_waitersCount; 391 ++_waitersCount;
392 } 392 }
393 393
394 /// <summary> 394 /// <summary>
395 /// Pop a waiter from the waiter's stack 395 /// Pop a waiter from the waiter's stack
396 /// </summary> 396 /// </summary>
397 /// <returns>Returns the first waiter in the stack</returns> 397 /// <returns>Returns the first waiter in the stack</returns>
398 private WaiterEntry PopWaiter() 398 private WaiterEntry PopWaiter()
399 { 399 {
400 // Store the current stack head 400 // Store the current stack head
401 WaiterEntry oldFirstWaiterEntry = _headWaiterEntry._nextWaiterEntry; 401 WaiterEntry oldFirstWaiterEntry = _headWaiterEntry._nextWaiterEntry;
402 402
403 // Store the new stack head 403 // Store the new stack head
404 WaiterEntry newHeadWaiterEntry = oldFirstWaiterEntry._nextWaiterEntry; 404 WaiterEntry newHeadWaiterEntry = oldFirstWaiterEntry._nextWaiterEntry;
405 405
406 // Update the old stack head list links and decrement the number 406 // Update the old stack head list links and decrement the number
407 // waiters. 407 // waiters.
408 RemoveWaiter(oldFirstWaiterEntry, true); 408 RemoveWaiter(oldFirstWaiterEntry, true);
409 409
410 // Update the new stack head 410 // Update the new stack head
411 _headWaiterEntry._nextWaiterEntry = newHeadWaiterEntry; 411 _headWaiterEntry._nextWaiterEntry = newHeadWaiterEntry;
412 if (null != newHeadWaiterEntry) 412 if (null != newHeadWaiterEntry)
413 { 413 {
414 newHeadWaiterEntry._prevWaiterEntry = _headWaiterEntry; 414 newHeadWaiterEntry._prevWaiterEntry = _headWaiterEntry;
415 } 415 }
416 416
417 // Return the old stack head 417 // Return the old stack head
418 return oldFirstWaiterEntry; 418 return oldFirstWaiterEntry;
419 } 419 }
420 420
421 /// <summary> 421 /// <summary>
422 /// Remove a waiter from the stack 422 /// Remove a waiter from the stack
423 /// </summary> 423 /// </summary>
424 /// <param name="waiterEntry">A waiter entry to remove</param> 424 /// <param name="waiterEntry">A waiter entry to remove</param>
425 /// <param name="popDecrement">If true the waiter count is always decremented</param> 425 /// <param name="popDecrement">If true the waiter count is always decremented</param>
426 private void RemoveWaiter(WaiterEntry waiterEntry, bool popDecrement) 426 private void RemoveWaiter(WaiterEntry waiterEntry, bool popDecrement)
427 { 427 {
428 // Store the prev entry in the list 428 // Store the prev entry in the list
429 WaiterEntry prevWaiterEntry = waiterEntry._prevWaiterEntry; 429 WaiterEntry prevWaiterEntry = waiterEntry._prevWaiterEntry;
430 430
431 // Store the next entry in the list 431 // Store the next entry in the list
432 WaiterEntry nextWaiterEntry = waiterEntry._nextWaiterEntry; 432 WaiterEntry nextWaiterEntry = waiterEntry._nextWaiterEntry;
433 433
434 // A flag to indicate if we need to decrement the waiters count. 434 // A flag to indicate if we need to decrement the waiters count.
435 // If we got here from PopWaiter then we must decrement. 435 // If we got here from PopWaiter then we must decrement.
436 // If we got here from PushWaiter then we decrement only if 436 // If we got here from PushWaiter then we decrement only if
437 // the waiter was already in the stack. 437 // the waiter was already in the stack.
438 bool decrementCounter = popDecrement; 438 bool decrementCounter = popDecrement;
439 439
440 // Null the waiter's entry links 440 // Null the waiter's entry links
441 waiterEntry._prevWaiterEntry = null; 441 waiterEntry._prevWaiterEntry = null;
442 waiterEntry._nextWaiterEntry = null; 442 waiterEntry._nextWaiterEntry = null;
443 443
444 // If the waiter entry had a prev link then update it. 444 // If the waiter entry had a prev link then update it.
445 // It also means that the waiter is already in the list and we 445 // It also means that the waiter is already in the list and we
446 // need to decrement the waiters count. 446 // need to decrement the waiters count.
447 if (null != prevWaiterEntry) 447 if (null != prevWaiterEntry)
448 { 448 {
449 prevWaiterEntry._nextWaiterEntry = nextWaiterEntry; 449 prevWaiterEntry._nextWaiterEntry = nextWaiterEntry;
450 decrementCounter = true; 450 decrementCounter = true;
451 } 451 }
452 452
453 // If the waiter entry had a next link then update it. 453 // If the waiter entry had a next link then update it.
454 // It also means that the waiter is already in the list and we 454 // It also means that the waiter is already in the list and we
455 // need to decrement the waiters count. 455 // need to decrement the waiters count.
456 if (null != nextWaiterEntry) 456 if (null != nextWaiterEntry)
457 { 457 {
458 nextWaiterEntry._prevWaiterEntry = prevWaiterEntry; 458 nextWaiterEntry._prevWaiterEntry = prevWaiterEntry;
459 decrementCounter = true; 459 decrementCounter = true;
460 } 460 }
461 461
462 // Decrement the waiters count if needed 462 // Decrement the waiters count if needed
463 if (decrementCounter) 463 if (decrementCounter)
464 { 464 {
465 --_waitersCount; 465 --_waitersCount;
466 } 466 }
467 } 467 }
468 468
469 #endregion 469 #endregion
470 470
471 #endregion 471 #endregion
472 472
473 #region WaiterEntry class 473 #region WaiterEntry class
474 474
475 // A waiter entry in the _waiters queue. 475 // A waiter entry in the _waiters queue.
476 public sealed class WaiterEntry : IDisposable 476 public sealed class WaiterEntry : IDisposable
477 { 477 {
478 #region Member variables 478 #region Member variables
479 479
480 /// <summary> 480 /// <summary>
481 /// Event to signal the waiter that it got the work item. 481 /// Event to signal the waiter that it got the work item.
482 /// </summary> 482 /// </summary>
483 //private AutoResetEvent _waitHandle = new AutoResetEvent(false); 483 //private AutoResetEvent _waitHandle = new AutoResetEvent(false);
484 private AutoResetEvent _waitHandle = EventWaitHandleFactory.CreateAutoResetEvent(); 484 private AutoResetEvent _waitHandle = EventWaitHandleFactory.CreateAutoResetEvent();
485 485
486 /// <summary> 486 /// <summary>
487 /// Flag to know if this waiter already quited from the queue 487 /// Flag to know if this waiter already quited from the queue
488 /// because of a timeout. 488 /// because of a timeout.
489 /// </summary> 489 /// </summary>
490 private bool _isTimedout = false; 490 private bool _isTimedout = false;
491 491
492 /// <summary> 492 /// <summary>
493 /// Flag to know if the waiter was signaled and got a work item. 493 /// Flag to know if the waiter was signaled and got a work item.
494 /// </summary> 494 /// </summary>
495 private bool _isSignaled = false; 495 private bool _isSignaled = false;
496 496
497 /// <summary> 497 /// <summary>
498 /// A work item that passed directly to the waiter withou going 498 /// A work item that passed directly to the waiter withou going
499 /// through the queue 499 /// through the queue
500 /// </summary> 500 /// </summary>
501 private WorkItem _workItem = null; 501 private WorkItem _workItem = null;
502 502
503 private bool _isDisposed = false; 503 private bool _isDisposed = false;
504 504
505 // Linked list members 505 // Linked list members
506 internal WaiterEntry _nextWaiterEntry = null; 506 internal WaiterEntry _nextWaiterEntry = null;
507 internal WaiterEntry _prevWaiterEntry = null; 507 internal WaiterEntry _prevWaiterEntry = null;
508 508
509 #endregion 509 #endregion
510 510
511 #region Construction 511 #region Construction
512 512
513 public WaiterEntry() 513 public WaiterEntry()
514 { 514 {
515 Reset(); 515 Reset();
516 } 516 }
517 517
518 #endregion 518 #endregion
519 519
520 #region Public methods 520 #region Public methods
521 521
522 public WaitHandle WaitHandle 522 public WaitHandle WaitHandle
523 { 523 {
524 get { return _waitHandle; } 524 get { return _waitHandle; }
525 } 525 }
526 526
527 public WorkItem WorkItem 527 public WorkItem WorkItem
528 { 528 {
529 get 529 get
530 { 530 {
531 return _workItem; 531 return _workItem;
532 } 532 }
533 } 533 }
534 534
535 /// <summary> 535 /// <summary>
536 /// Signal the waiter that it got a work item. 536 /// Signal the waiter that it got a work item.
537 /// </summary> 537 /// </summary>
538 /// <returns>Return true on success</returns> 538 /// <returns>Return true on success</returns>
539 /// The method fails if Timeout() preceded its call 539 /// The method fails if Timeout() preceded its call
540 public bool Signal(WorkItem workItem) 540 public bool Signal(WorkItem workItem)
541 { 541 {
542 lock(this) 542 lock(this)
543 { 543 {
544 if (!_isTimedout) 544 if (!_isTimedout)
545 { 545 {
546 _workItem = workItem; 546 _workItem = workItem;
547 _isSignaled = true; 547 _isSignaled = true;
548 _waitHandle.Set(); 548 _waitHandle.Set();
549 return true; 549 return true;
550 } 550 }
551 } 551 }
552 return false; 552 return false;
553 } 553 }
554 554
555 /// <summary> 555 /// <summary>
556 /// Mark the wait entry that it has been timed out 556 /// Mark the wait entry that it has been timed out
557 /// </summary> 557 /// </summary>
558 /// <returns>Return true on success</returns> 558 /// <returns>Return true on success</returns>
559 /// The method fails if Signal() preceded its call 559 /// The method fails if Signal() preceded its call
560 public bool Timeout() 560 public bool Timeout()
561 { 561 {
562 lock(this) 562 lock(this)
563 { 563 {
564 // Time out can happen only if the waiter wasn't marked as 564 // Time out can happen only if the waiter wasn't marked as
565 // signaled 565 // signaled
566 if (!_isSignaled) 566 if (!_isSignaled)
567 { 567 {
568 // We don't remove the waiter from the queue, the DequeueWorkItem 568 // We don't remove the waiter from the queue, the DequeueWorkItem
569 // method skips _waiters that were timed out. 569 // method skips _waiters that were timed out.
570 _isTimedout = true; 570 _isTimedout = true;
571 return true; 571 return true;
572 } 572 }
573 } 573 }
574 return false; 574 return false;
575 } 575 }
576 576
577 /// <summary> 577 /// <summary>
578 /// Reset the wait entry so it can be used again 578 /// Reset the wait entry so it can be used again
579 /// </summary> 579 /// </summary>
580 public void Reset() 580 public void Reset()
581 { 581 {
582 _workItem = null; 582 _workItem = null;
583 _isTimedout = false; 583 _isTimedout = false;
584 _isSignaled = false; 584 _isSignaled = false;
585 _waitHandle.Reset(); 585 _waitHandle.Reset();
586 } 586 }
587 587
588 /// <summary> 588 /// <summary>
589 /// Free resources 589 /// Free resources
590 /// </summary> 590 /// </summary>
591 public void Close() 591 public void Close()
592 { 592 {
593 if (null != _waitHandle) 593 if (null != _waitHandle)
594 { 594 {
595 _waitHandle.Close(); 595 _waitHandle.Close();
596 _waitHandle = null; 596 _waitHandle = null;
597 } 597 }
598 } 598 }
599 599
600 #endregion 600 #endregion
601 601
602 #region IDisposable Members 602 #region IDisposable Members
603 603
604 public void Dispose() 604 public void Dispose()
605 { 605 {
606 lock (this) 606 lock (this)
607 { 607 {
608 if (!_isDisposed) 608 if (!_isDisposed)
609 { 609 {
610 Close(); 610 Close();
611 } 611 }
612 _isDisposed = true; 612 _isDisposed = true;
613 } 613 }
614 } 614 }
615 615
616 #endregion 616 #endregion
617 } 617 }
618 618
619 #endregion 619 #endregion
620 620
621 #region IDisposable Members 621 #region IDisposable Members
622 622
623 public void Dispose() 623 public void Dispose()
624 { 624 {
625 if (!_isDisposed) 625 if (!_isDisposed)
626 { 626 {
627 Cleanup(); 627 Cleanup();
628 } 628 }
629 _isDisposed = true; 629 _isDisposed = true;
630 } 630 }
631 631
632 private void ValidateNotDisposed() 632 private void ValidateNotDisposed()
633 { 633 {
634 if(_isDisposed) 634 if(_isDisposed)
635 { 635 {
636 throw new ObjectDisposedException(GetType().ToString(), "The SmartThreadPool has been shutdown"); 636 throw new ObjectDisposedException(GetType().ToString(), "The SmartThreadPool has been shutdown");
637 } 637 }
638 } 638 }
639 639
640 #endregion 640 #endregion
641 } 641 }
642 642
643 #endregion 643 #endregion
644} 644}
645 645