浏览代码

Fix SmartThreadPool line endings in recent update from dos to unix

Justin Clark-Casey (justincc) 11 年之前
父节点
当前提交
854dcd1abd

+ 138 - 138
ThirdParty/SmartThreadPool/CallerThreadContext.cs

@@ -1,138 +1,138 @@
-
-#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
-
-using System;
-using System.Diagnostics;
-using System.Threading;
-using System.Reflection;
-using System.Web;
-using System.Runtime.Remoting.Messaging;
-
-
-namespace Amib.Threading.Internal
-{
-#region CallerThreadContext class
-
-	/// <summary>
-	/// This class stores the caller call context in order to restore
-	/// it when the work item is executed in the thread pool environment. 
-	/// </summary>
-	internal class CallerThreadContext 
-	{
-#region Prepare reflection information
-
-		// Cached type information.
-		private static readonly MethodInfo getLogicalCallContextMethodInfo =
-			typeof(Thread).GetMethod("GetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic);
-
-		private static readonly MethodInfo setLogicalCallContextMethodInfo =
-			typeof(Thread).GetMethod("SetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic);
-
-		private static string HttpContextSlotName = GetHttpContextSlotName();
-
-		private static string GetHttpContextSlotName()
-		{
-			FieldInfo fi = typeof(HttpContext).GetField("CallContextSlotName", BindingFlags.Static | BindingFlags.NonPublic);
-
-            if (fi != null)
-            {
-                return (string) fi.GetValue(null);
-            }
-
-		    return "HttpContext";
-		}
-
-        #endregion
-
-#region Private fields
-
-		private HttpContext _httpContext;
-		private LogicalCallContext _callContext;
-
-        #endregion
-
-		/// <summary>
-		/// Constructor
-		/// </summary>
-		private CallerThreadContext()
-		{
-		}
-
-		public bool CapturedCallContext
-		{
-			get
-			{
-				return (null != _callContext);
-			}
-		}
-
-		public bool CapturedHttpContext
-		{
-			get
-			{
-				return (null != _httpContext);
-			}
-		}
-
-		/// <summary>
-		/// Captures the current thread context
-		/// </summary>
-		/// <returns></returns>
-		public static CallerThreadContext Capture(
-			bool captureCallContext, 
-			bool captureHttpContext)
-		{
-			Debug.Assert(captureCallContext || captureHttpContext);
-
-			CallerThreadContext callerThreadContext = new CallerThreadContext();
-
-			// TODO: In NET 2.0, redo using the new feature of ExecutionContext class - Capture()
-			// Capture Call Context
-			if(captureCallContext && (getLogicalCallContextMethodInfo != null))
-			{
-				callerThreadContext._callContext = (LogicalCallContext)getLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, null);
-				if (callerThreadContext._callContext != null)
-				{
-					callerThreadContext._callContext = (LogicalCallContext)callerThreadContext._callContext.Clone();
-				}
-			}
-
-			// Capture httpContext
-			if (captureHttpContext && (null != HttpContext.Current))
-			{
-				callerThreadContext._httpContext = HttpContext.Current;
-			}
-
-			return callerThreadContext;
-		}
-
-		/// <summary>
-		/// Applies the thread context stored earlier
-		/// </summary>
-		/// <param name="callerThreadContext"></param>
-		public static void Apply(CallerThreadContext callerThreadContext)
-		{
-			if (null == callerThreadContext) 
-			{
-				throw new ArgumentNullException("callerThreadContext");			
-			}
-
-			// Todo: In NET 2.0, redo using the new feature of ExecutionContext class - Run()
-			// Restore call context
-			if ((callerThreadContext._callContext != null) && (setLogicalCallContextMethodInfo != null))
-			{
-				setLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, new object[] { callerThreadContext._callContext });
-			}
-
-			// Restore HttpContext 
-			if (callerThreadContext._httpContext != null)
-			{
-                HttpContext.Current = callerThreadContext._httpContext;
-				//CallContext.SetData(HttpContextSlotName, callerThreadContext._httpContext);
-			}
-		}
-	}
-
-    #endregion
-}
-#endif
+
+#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
+
+using System;
+using System.Diagnostics;
+using System.Threading;
+using System.Reflection;
+using System.Web;
+using System.Runtime.Remoting.Messaging;
+
+
+namespace Amib.Threading.Internal
+{
+#region CallerThreadContext class
+
+	/// <summary>
+	/// This class stores the caller call context in order to restore
+	/// it when the work item is executed in the thread pool environment. 
+	/// </summary>
+	internal class CallerThreadContext 
+	{
+#region Prepare reflection information
+
+		// Cached type information.
+		private static readonly MethodInfo getLogicalCallContextMethodInfo =
+			typeof(Thread).GetMethod("GetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic);
+
+		private static readonly MethodInfo setLogicalCallContextMethodInfo =
+			typeof(Thread).GetMethod("SetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic);
+
+		private static string HttpContextSlotName = GetHttpContextSlotName();
+
+		private static string GetHttpContextSlotName()
+		{
+			FieldInfo fi = typeof(HttpContext).GetField("CallContextSlotName", BindingFlags.Static | BindingFlags.NonPublic);
+
+            if (fi != null)
+            {
+                return (string) fi.GetValue(null);
+            }
+
+		    return "HttpContext";
+		}
+
+        #endregion
+
+#region Private fields
+
+		private HttpContext _httpContext;
+		private LogicalCallContext _callContext;
+
+        #endregion
+
+		/// <summary>
+		/// Constructor
+		/// </summary>
+		private CallerThreadContext()
+		{
+		}
+
+		public bool CapturedCallContext
+		{
+			get
+			{
+				return (null != _callContext);
+			}
+		}
+
+		public bool CapturedHttpContext
+		{
+			get
+			{
+				return (null != _httpContext);
+			}
+		}
+
+		/// <summary>
+		/// Captures the current thread context
+		/// </summary>
+		/// <returns></returns>
+		public static CallerThreadContext Capture(
+			bool captureCallContext, 
+			bool captureHttpContext)
+		{
+			Debug.Assert(captureCallContext || captureHttpContext);
+
+			CallerThreadContext callerThreadContext = new CallerThreadContext();
+
+			// TODO: In NET 2.0, redo using the new feature of ExecutionContext class - Capture()
+			// Capture Call Context
+			if(captureCallContext && (getLogicalCallContextMethodInfo != null))
+			{
+				callerThreadContext._callContext = (LogicalCallContext)getLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, null);
+				if (callerThreadContext._callContext != null)
+				{
+					callerThreadContext._callContext = (LogicalCallContext)callerThreadContext._callContext.Clone();
+				}
+			}
+
+			// Capture httpContext
+			if (captureHttpContext && (null != HttpContext.Current))
+			{
+				callerThreadContext._httpContext = HttpContext.Current;
+			}
+
+			return callerThreadContext;
+		}
+
+		/// <summary>
+		/// Applies the thread context stored earlier
+		/// </summary>
+		/// <param name="callerThreadContext"></param>
+		public static void Apply(CallerThreadContext callerThreadContext)
+		{
+			if (null == callerThreadContext) 
+			{
+				throw new ArgumentNullException("callerThreadContext");			
+			}
+
+			// Todo: In NET 2.0, redo using the new feature of ExecutionContext class - Run()
+			// Restore call context
+			if ((callerThreadContext._callContext != null) && (setLogicalCallContextMethodInfo != null))
+			{
+				setLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, new object[] { callerThreadContext._callContext });
+			}
+
+			// Restore HttpContext 
+			if (callerThreadContext._httpContext != null)
+			{
+                HttpContext.Current = callerThreadContext._httpContext;
+				//CallContext.SetData(HttpContextSlotName, callerThreadContext._httpContext);
+			}
+		}
+	}
+
+    #endregion
+}
+#endif

+ 13 - 13
ThirdParty/SmartThreadPool/CanceledWorkItemsGroup.cs

@@ -1,14 +1,14 @@
-namespace Amib.Threading.Internal
-{
-    internal class CanceledWorkItemsGroup
-    {
-        public readonly static CanceledWorkItemsGroup NotCanceledWorkItemsGroup = new CanceledWorkItemsGroup();
-
-        public CanceledWorkItemsGroup()
-        {
-            IsCanceled = false;
-        }
-
-        public bool IsCanceled { get; set; }
-    }
+namespace Amib.Threading.Internal
+{
+    internal class CanceledWorkItemsGroup
+    {
+        public readonly static CanceledWorkItemsGroup NotCanceledWorkItemsGroup = new CanceledWorkItemsGroup();
+
+        public CanceledWorkItemsGroup()
+        {
+            IsCanceled = false;
+        }
+
+        public bool IsCanceled { get; set; }
+    }
 }

+ 103 - 103
ThirdParty/SmartThreadPool/EventWaitHandle.cs

@@ -1,104 +1,104 @@
-#if (_WINDOWS_CE)
-
-using System;
-using System.Runtime.InteropServices;
-using System.Threading;
-
-namespace Amib.Threading.Internal
-{
-    /// <summary>
-    /// EventWaitHandle class
-    /// In WindowsCE this class doesn't exist and I needed the WaitAll and WaitAny implementation.
-    /// So I wrote this class to implement these two methods with some of their overloads.
-    /// It uses the WaitForMultipleObjects API to do the WaitAll and WaitAny.
-    /// Note that this class doesn't even inherit from WaitHandle!
-    /// </summary>
-    public class STPEventWaitHandle
-    {
-        #region Public Constants
-
-        public const int WaitTimeout = Timeout.Infinite;
-
-        #endregion
-
-        #region Private External Constants
-
-        private const Int32 WAIT_FAILED = -1;
-        private const Int32 WAIT_TIMEOUT = 0x102;
-        private const UInt32 INFINITE = 0xFFFFFFFF;
-
-        #endregion
-
-        #region WaitAll and WaitAny
-
-        internal static bool WaitOne(WaitHandle waitHandle, int millisecondsTimeout, bool exitContext)
-        {
-            return waitHandle.WaitOne(millisecondsTimeout, exitContext);
-        }
-
-	    private static IntPtr[] PrepareNativeHandles(WaitHandle[] waitHandles)
-	    {
-	        IntPtr[] nativeHandles = new IntPtr[waitHandles.Length];
-	        for (int i = 0; i < waitHandles.Length; i++)
-	        {
-                nativeHandles[i] = waitHandles[i].Handle;
-	        }
-	        return nativeHandles;
-	    }
-
-	    public static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
-	    {
-            uint timeout = millisecondsTimeout < 0 ? INFINITE : (uint)millisecondsTimeout;
-
-            IntPtr[] nativeHandles = PrepareNativeHandles(waitHandles);
-
-	        int result = WaitForMultipleObjects((uint)waitHandles.Length, nativeHandles, true, timeout);
-
-            if (result == WAIT_TIMEOUT || result == WAIT_FAILED)
-            {
-                return false;
-            }
-
-	        return true;
-	    }
-
-
-	    public static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
-        {
-            uint timeout = millisecondsTimeout < 0 ? INFINITE : (uint)millisecondsTimeout;
-
-            IntPtr[] nativeHandles = PrepareNativeHandles(waitHandles);
-
-            int result = WaitForMultipleObjects((uint)waitHandles.Length, nativeHandles, false, timeout);
-
-            if (result >= 0 && result < waitHandles.Length)
-            {
-                return result;
-            }
-
-            return -1;
-        }
-
-        public static int WaitAny(WaitHandle[] waitHandles)
-        {
-            return WaitAny(waitHandles, Timeout.Infinite, false);
-        }
-
-        public static int WaitAny(WaitHandle[] waitHandles, TimeSpan timeout, bool exitContext)
-        {
-            int millisecondsTimeout = (int)timeout.TotalMilliseconds;
-
-            return WaitAny(waitHandles, millisecondsTimeout, false);
-        }
- 
-        #endregion
-
-        #region External methods
-
-        [DllImport("coredll.dll", SetLastError = true)]
-        public static extern int WaitForMultipleObjects(uint nCount, IntPtr[] lpHandles, bool fWaitAll, uint dwMilliseconds);
-
-        #endregion
-    }
-}
+#if (_WINDOWS_CE)
+
+using System;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+namespace Amib.Threading.Internal
+{
+    /// <summary>
+    /// EventWaitHandle class
+    /// In WindowsCE this class doesn't exist and I needed the WaitAll and WaitAny implementation.
+    /// So I wrote this class to implement these two methods with some of their overloads.
+    /// It uses the WaitForMultipleObjects API to do the WaitAll and WaitAny.
+    /// Note that this class doesn't even inherit from WaitHandle!
+    /// </summary>
+    public class STPEventWaitHandle
+    {
+        #region Public Constants
+
+        public const int WaitTimeout = Timeout.Infinite;
+
+        #endregion
+
+        #region Private External Constants
+
+        private const Int32 WAIT_FAILED = -1;
+        private const Int32 WAIT_TIMEOUT = 0x102;
+        private const UInt32 INFINITE = 0xFFFFFFFF;
+
+        #endregion
+
+        #region WaitAll and WaitAny
+
+        internal static bool WaitOne(WaitHandle waitHandle, int millisecondsTimeout, bool exitContext)
+        {
+            return waitHandle.WaitOne(millisecondsTimeout, exitContext);
+        }
+
+	    private static IntPtr[] PrepareNativeHandles(WaitHandle[] waitHandles)
+	    {
+	        IntPtr[] nativeHandles = new IntPtr[waitHandles.Length];
+	        for (int i = 0; i < waitHandles.Length; i++)
+	        {
+                nativeHandles[i] = waitHandles[i].Handle;
+	        }
+	        return nativeHandles;
+	    }
+
+	    public static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
+	    {
+            uint timeout = millisecondsTimeout < 0 ? INFINITE : (uint)millisecondsTimeout;
+
+            IntPtr[] nativeHandles = PrepareNativeHandles(waitHandles);
+
+	        int result = WaitForMultipleObjects((uint)waitHandles.Length, nativeHandles, true, timeout);
+
+            if (result == WAIT_TIMEOUT || result == WAIT_FAILED)
+            {
+                return false;
+            }
+
+	        return true;
+	    }
+
+
+	    public static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
+        {
+            uint timeout = millisecondsTimeout < 0 ? INFINITE : (uint)millisecondsTimeout;
+
+            IntPtr[] nativeHandles = PrepareNativeHandles(waitHandles);
+
+            int result = WaitForMultipleObjects((uint)waitHandles.Length, nativeHandles, false, timeout);
+
+            if (result >= 0 && result < waitHandles.Length)
+            {
+                return result;
+            }
+
+            return -1;
+        }
+
+        public static int WaitAny(WaitHandle[] waitHandles)
+        {
+            return WaitAny(waitHandles, Timeout.Infinite, false);
+        }
+
+        public static int WaitAny(WaitHandle[] waitHandles, TimeSpan timeout, bool exitContext)
+        {
+            int millisecondsTimeout = (int)timeout.TotalMilliseconds;
+
+            return WaitAny(waitHandles, millisecondsTimeout, false);
+        }
+ 
+        #endregion
+
+        #region External methods
+
+        [DllImport("coredll.dll", SetLastError = true)]
+        public static extern int WaitForMultipleObjects(uint nCount, IntPtr[] lpHandles, bool fWaitAll, uint dwMilliseconds);
+
+        #endregion
+    }
+}
 #endif

+ 82 - 82
ThirdParty/SmartThreadPool/EventWaitHandleFactory.cs

@@ -1,82 +1,82 @@
-using System.Threading;
-
-#if (_WINDOWS_CE)
-using System;
-using System.Runtime.InteropServices;
-#endif
-
-namespace Amib.Threading.Internal
-{
-    /// <summary>
-    /// EventWaitHandleFactory class.
-    /// This is a static class that creates AutoResetEvent and ManualResetEvent objects.
-    /// In WindowCE the WaitForMultipleObjects API fails to use the Handle property 
-    /// of XxxResetEvent. It can use only handles that were created by the CreateEvent API.
-    /// Consequently this class creates the needed XxxResetEvent and replaces the handle if
-    /// it's a WindowsCE OS.
-    /// </summary>
-    public static class EventWaitHandleFactory
-    {
-        /// <summary>
-        /// Create a new AutoResetEvent object
-        /// </summary>
-        /// <returns>Return a new AutoResetEvent object</returns>
-        public static AutoResetEvent CreateAutoResetEvent()
-        {
-            AutoResetEvent waitHandle = new AutoResetEvent(false);
-
-#if (_WINDOWS_CE)
-            ReplaceEventHandle(waitHandle, false, false);
-#endif
-
-            return waitHandle;
-        }
-
-        /// <summary>
-        /// Create a new ManualResetEvent object
-        /// </summary>
-        /// <returns>Return a new ManualResetEvent object</returns>
-        public static ManualResetEvent CreateManualResetEvent(bool initialState)
-        {
-            ManualResetEvent waitHandle = new ManualResetEvent(initialState);
-
-#if (_WINDOWS_CE)
-            ReplaceEventHandle(waitHandle, true, initialState);
-#endif
-
-            return waitHandle;
-        }
-
-#if (_WINDOWS_CE)
-
-        /// <summary>
-        /// Replace the event handle
-        /// </summary>
-        /// <param name="waitHandle">The WaitHandle object which its handle needs to be replaced.</param>
-        /// <param name="manualReset">Indicates if the event is a ManualResetEvent (true) or an AutoResetEvent (false)</param>
-        /// <param name="initialState">The initial state of the event</param>
-        private static void ReplaceEventHandle(WaitHandle waitHandle, bool manualReset, bool initialState)
-        {
-            // Store the old handle 
-            IntPtr oldHandle = waitHandle.Handle;
-
-            // Create a new event
-            IntPtr newHandle = CreateEvent(IntPtr.Zero, manualReset, initialState, null);
-
-            // Replace the old event with the new event
-            waitHandle.Handle = newHandle;
-
-            // Close the old event
-            CloseHandle (oldHandle);        
-        }
-
-        [DllImport("coredll.dll", SetLastError = true)]
-        public static extern IntPtr CreateEvent(IntPtr lpEventAttributes, bool bManualReset, bool bInitialState, string lpName);
-
-        //Handle
-        [DllImport("coredll.dll", SetLastError = true)]
-        public static extern bool CloseHandle(IntPtr hObject);
-#endif
-
-    }
-}
+using System.Threading;
+
+#if (_WINDOWS_CE)
+using System;
+using System.Runtime.InteropServices;
+#endif
+
+namespace Amib.Threading.Internal
+{
+    /// <summary>
+    /// EventWaitHandleFactory class.
+    /// This is a static class that creates AutoResetEvent and ManualResetEvent objects.
+    /// In WindowCE the WaitForMultipleObjects API fails to use the Handle property 
+    /// of XxxResetEvent. It can use only handles that were created by the CreateEvent API.
+    /// Consequently this class creates the needed XxxResetEvent and replaces the handle if
+    /// it's a WindowsCE OS.
+    /// </summary>
+    public static class EventWaitHandleFactory
+    {
+        /// <summary>
+        /// Create a new AutoResetEvent object
+        /// </summary>
+        /// <returns>Return a new AutoResetEvent object</returns>
+        public static AutoResetEvent CreateAutoResetEvent()
+        {
+            AutoResetEvent waitHandle = new AutoResetEvent(false);
+
+#if (_WINDOWS_CE)
+            ReplaceEventHandle(waitHandle, false, false);
+#endif
+
+            return waitHandle;
+        }
+
+        /// <summary>
+        /// Create a new ManualResetEvent object
+        /// </summary>
+        /// <returns>Return a new ManualResetEvent object</returns>
+        public static ManualResetEvent CreateManualResetEvent(bool initialState)
+        {
+            ManualResetEvent waitHandle = new ManualResetEvent(initialState);
+
+#if (_WINDOWS_CE)
+            ReplaceEventHandle(waitHandle, true, initialState);
+#endif
+
+            return waitHandle;
+        }
+
+#if (_WINDOWS_CE)
+
+        /// <summary>
+        /// Replace the event handle
+        /// </summary>
+        /// <param name="waitHandle">The WaitHandle object which its handle needs to be replaced.</param>
+        /// <param name="manualReset">Indicates if the event is a ManualResetEvent (true) or an AutoResetEvent (false)</param>
+        /// <param name="initialState">The initial state of the event</param>
+        private static void ReplaceEventHandle(WaitHandle waitHandle, bool manualReset, bool initialState)
+        {
+            // Store the old handle 
+            IntPtr oldHandle = waitHandle.Handle;
+
+            // Create a new event
+            IntPtr newHandle = CreateEvent(IntPtr.Zero, manualReset, initialState, null);
+
+            // Replace the old event with the new event
+            waitHandle.Handle = newHandle;
+
+            // Close the old event
+            CloseHandle (oldHandle);        
+        }
+
+        [DllImport("coredll.dll", SetLastError = true)]
+        public static extern IntPtr CreateEvent(IntPtr lpEventAttributes, bool bManualReset, bool bInitialState, string lpName);
+
+        //Handle
+        [DllImport("coredll.dll", SetLastError = true)]
+        public static extern bool CloseHandle(IntPtr hObject);
+#endif
+
+    }
+}

+ 111 - 111
ThirdParty/SmartThreadPool/Exceptions.cs

@@ -1,111 +1,111 @@
-using System;
-#if !(_WINDOWS_CE)
-using System.Runtime.Serialization;
-#endif
-
-namespace Amib.Threading
-{
-    #region Exceptions
-
-    /// <summary>
-    /// Represents an exception in case IWorkItemResult.GetResult has been canceled
-    /// </summary>
-    public sealed partial class WorkItemCancelException : Exception
-    {
-        public WorkItemCancelException()
-        {
-        }
-
-        public WorkItemCancelException(string message)
-            : base(message)
-        {
-        }
-
-        public WorkItemCancelException(string message, Exception e)
-            : base(message, e)
-        {
-        }
-    }
-
-    /// <summary>
-    /// Represents an exception in case IWorkItemResult.GetResult has been timed out
-    /// </summary>
-    public sealed partial class WorkItemTimeoutException : Exception
-    {
-        public WorkItemTimeoutException()
-        {
-        }
-
-        public WorkItemTimeoutException(string message)
-            : base(message)
-        {
-        }
-
-        public WorkItemTimeoutException(string message, Exception e)
-            : base(message, e)
-        {
-        }
-    }
-
-    /// <summary>
-    /// Represents an exception in case IWorkItemResult.GetResult has been timed out
-    /// </summary>
-    public sealed partial class WorkItemResultException : Exception
-    {
-        public WorkItemResultException()
-        {
-        }
-
-        public WorkItemResultException(string message)
-            : base(message)
-        {
-        }
-
-        public WorkItemResultException(string message, Exception e)
-            : base(message, e)
-        {
-        }
-    }
-
-
-#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
-    /// <summary>
-    /// Represents an exception in case IWorkItemResult.GetResult has been canceled
-    /// </summary>
-    [Serializable]
-    public sealed partial class WorkItemCancelException
-    {
-        public WorkItemCancelException(SerializationInfo si, StreamingContext sc)
-            : base(si, sc)
-        {
-        }
-    }
-
-    /// <summary>
-    /// Represents an exception in case IWorkItemResult.GetResult has been timed out
-    /// </summary>
-    [Serializable]
-    public sealed partial class WorkItemTimeoutException
-    {
-        public WorkItemTimeoutException(SerializationInfo si, StreamingContext sc)
-            : base(si, sc)
-        {
-        }
-    }
-
-    /// <summary>
-    /// Represents an exception in case IWorkItemResult.GetResult has been timed out
-    /// </summary>
-    [Serializable]
-    public sealed partial class WorkItemResultException
-    {
-        public WorkItemResultException(SerializationInfo si, StreamingContext sc)
-            : base(si, sc)
-        {
-        }
-    }
-
-#endif
-
-    #endregion
-}
+using System;
+#if !(_WINDOWS_CE)
+using System.Runtime.Serialization;
+#endif
+
+namespace Amib.Threading
+{
+    #region Exceptions
+
+    /// <summary>
+    /// Represents an exception in case IWorkItemResult.GetResult has been canceled
+    /// </summary>
+    public sealed partial class WorkItemCancelException : Exception
+    {
+        public WorkItemCancelException()
+        {
+        }
+
+        public WorkItemCancelException(string message)
+            : base(message)
+        {
+        }
+
+        public WorkItemCancelException(string message, Exception e)
+            : base(message, e)
+        {
+        }
+    }
+
+    /// <summary>
+    /// Represents an exception in case IWorkItemResult.GetResult has been timed out
+    /// </summary>
+    public sealed partial class WorkItemTimeoutException : Exception
+    {
+        public WorkItemTimeoutException()
+        {
+        }
+
+        public WorkItemTimeoutException(string message)
+            : base(message)
+        {
+        }
+
+        public WorkItemTimeoutException(string message, Exception e)
+            : base(message, e)
+        {
+        }
+    }
+
+    /// <summary>
+    /// Represents an exception in case IWorkItemResult.GetResult has been timed out
+    /// </summary>
+    public sealed partial class WorkItemResultException : Exception
+    {
+        public WorkItemResultException()
+        {
+        }
+
+        public WorkItemResultException(string message)
+            : base(message)
+        {
+        }
+
+        public WorkItemResultException(string message, Exception e)
+            : base(message, e)
+        {
+        }
+    }
+
+
+#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
+    /// <summary>
+    /// Represents an exception in case IWorkItemResult.GetResult has been canceled
+    /// </summary>
+    [Serializable]
+    public sealed partial class WorkItemCancelException
+    {
+        public WorkItemCancelException(SerializationInfo si, StreamingContext sc)
+            : base(si, sc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// Represents an exception in case IWorkItemResult.GetResult has been timed out
+    /// </summary>
+    [Serializable]
+    public sealed partial class WorkItemTimeoutException
+    {
+        public WorkItemTimeoutException(SerializationInfo si, StreamingContext sc)
+            : base(si, sc)
+        {
+        }
+    }
+
+    /// <summary>
+    /// Represents an exception in case IWorkItemResult.GetResult has been timed out
+    /// </summary>
+    [Serializable]
+    public sealed partial class WorkItemResultException
+    {
+        public WorkItemResultException(SerializationInfo si, StreamingContext sc)
+            : base(si, sc)
+        {
+        }
+    }
+
+#endif
+
+    #endregion
+}

+ 628 - 628
ThirdParty/SmartThreadPool/Interfaces.cs

@@ -1,628 +1,628 @@
-using System;
-using System.Threading;
-
-namespace Amib.Threading
-{
-	#region Delegates
-
-	/// <summary>
-	/// A delegate that represents the method to run as the work item
-	/// </summary>
-	/// <param name="state">A state object for the method to run</param>
-	public delegate object WorkItemCallback(object state);
-
-	/// <summary>
-	/// A delegate to call after the WorkItemCallback completed
-	/// </summary>
-	/// <param name="wir">The work item result object</param>
-    public delegate void PostExecuteWorkItemCallback(IWorkItemResult wir);
-
-    /// <summary>
-    /// A delegate to call after the WorkItemCallback completed
-    /// </summary>
-    /// <param name="wir">The work item result object</param>
-    public delegate void PostExecuteWorkItemCallback<TResult>(IWorkItemResult<TResult> wir);
-
-	/// <summary>
-	/// A delegate to call when a WorkItemsGroup becomes idle
-	/// </summary>
-	/// <param name="workItemsGroup">A reference to the WorkItemsGroup that became idle</param>
-	public delegate void WorkItemsGroupIdleHandler(IWorkItemsGroup workItemsGroup);
-
-    /// <summary>
-    /// A delegate to call after a thread is created, but before 
-    /// it's first use.
-    /// </summary>
-    public delegate void ThreadInitializationHandler();
-
-    /// <summary>
-    /// A delegate to call when a thread is about to exit, after 
-    /// it is no longer belong to the pool.
-    /// </summary>
-    public delegate void ThreadTerminationHandler();
-
-	#endregion
-
-	#region WorkItem Priority
-
-    /// <summary>
-    /// Defines the availeable priorities of a work item.
-    /// The higher the priority a work item has, the sooner
-    /// it will be executed.
-    /// </summary>
-	public enum WorkItemPriority
-	{
-		Lowest,
-		BelowNormal,
-		Normal,
-		AboveNormal,
-		Highest,
-	}
-
-	#endregion
-
-	#region IWorkItemsGroup interface 
-
-	/// <summary>
-	/// IWorkItemsGroup interface
-    /// Created by SmartThreadPool.CreateWorkItemsGroup()
-	/// </summary>
-	public interface IWorkItemsGroup
-	{
-		/// <summary>
-		/// Get/Set the name of the WorkItemsGroup
-		/// </summary>
-		string Name { get; set; }
-
-        /// <summary>
-        /// Get/Set the maximum number of workitem that execute cocurrency on the thread pool
-        /// </summary>
-        int Concurrency { get; set; }
-
-        /// <summary>
-        /// Get the number of work items waiting in the queue.
-        /// </summary>
-        int WaitingCallbacks { get; }
-
-        /// <summary>
-        /// Get an array with all the state objects of the currently running items.
-        /// The array represents a snap shot and impact performance.
-        /// </summary>
-        object[] GetStates();
-
-        /// <summary>
-        /// Get the WorkItemsGroup start information
-        /// </summary>
-        WIGStartInfo WIGStartInfo { get; }
-
-        /// <summary>
-        /// Starts to execute work items
-        /// </summary>
-        void Start();
-
-        /// <summary>
-        /// Cancel all the work items.
-        /// Same as Cancel(false)
-        /// </summary>
-        void Cancel();
-
-        /// <summary>
-        /// Cancel all work items using thread abortion
-        /// </summary>
-        /// <param name="abortExecution">True to stop work items by raising ThreadAbortException</param>
-        void Cancel(bool abortExecution);
-
-        /// <summary>
-        /// Wait for all work item to complete.
-        /// </summary>
-		void WaitForIdle();
-
-        /// <summary>
-        /// Wait for all work item to complete, until timeout expired
-        /// </summary>
-        /// <param name="timeout">How long to wait for the work items to complete</param>
-        /// <returns>Returns true if work items completed within the timeout, otherwise false.</returns>
-		bool WaitForIdle(TimeSpan timeout);
-
-        /// <summary>
-        /// Wait for all work item to complete, until timeout expired
-        /// </summary>
-        /// <param name="millisecondsTimeout">How long to wait for the work items to complete in milliseconds</param>
-        /// <returns>Returns true if work items completed within the timeout, otherwise false.</returns>
-        bool WaitForIdle(int millisecondsTimeout);
-
-        /// <summary>
-        /// IsIdle is true when there are no work items running or queued.
-        /// </summary>
-        bool IsIdle { get; }
-
-        /// <summary>
-        /// This event is fired when all work items are completed.
-        /// (When IsIdle changes to true)
-        /// This event only work on WorkItemsGroup. On SmartThreadPool
-        /// it throws the NotImplementedException.
-        /// </summary>
-        event WorkItemsGroupIdleHandler OnIdle;
-
-        #region QueueWorkItem
-
-        /// <summary>
-        /// Queue a work item
-        /// </summary>
-        /// <param name="callback">A callback to execute</param>
-        /// <returns>Returns a work item result</returns>        
-        IWorkItemResult QueueWorkItem(WorkItemCallback callback);
-
-        /// <summary>
-        /// Queue a work item
-        /// </summary>
-        /// <param name="callback">A callback to execute</param>
-        /// <param name="workItemPriority">The priority of the work item</param>
-        /// <returns>Returns a work item result</returns>
-        IWorkItemResult QueueWorkItem(WorkItemCallback callback, WorkItemPriority workItemPriority);
-
-        /// <summary>
-        /// Queue a work item
-        /// </summary>
-        /// <param name="callback">A callback to execute</param>
-        /// <param name="state">
-        /// The context object of the work item. Used for passing arguments to the work item. 
-        /// </param>
-        /// <returns>Returns a work item result</returns>
-        IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state);
-
-        /// <summary>
-        /// Queue a work item
-        /// </summary>
-        /// <param name="callback">A callback to execute</param>
-        /// <param name="state">
-        /// The context object of the work item. Used for passing arguments to the work item. 
-        /// </param>
-        /// <param name="workItemPriority">The work item priority</param>
-        /// <returns>Returns a work item result</returns>
-        IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, WorkItemPriority workItemPriority);
-
-        /// <summary>
-        /// Queue a work item
-        /// </summary>
-        /// <param name="callback">A callback to execute</param>
-        /// <param name="state">
-        /// The context object of the work item. Used for passing arguments to the work item. 
-        /// </param>
-        /// <param name="postExecuteWorkItemCallback">
-        /// A delegate to call after the callback completion
-        /// </param>
-        /// <returns>Returns a work item result</returns>
-        IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback);
-
-        /// <summary>
-        /// Queue a work item
-        /// </summary>
-        /// <param name="callback">A callback to execute</param>
-        /// <param name="state">
-        /// The context object of the work item. Used for passing arguments to the work item. 
-        /// </param>
-        /// <param name="postExecuteWorkItemCallback">
-        /// A delegate to call after the callback completion
-        /// </param>
-        /// <param name="workItemPriority">The work item priority</param>
-        /// <returns>Returns a work item result</returns>
-        IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, WorkItemPriority workItemPriority);
-
-        /// <summary>
-        /// Queue a work item
-        /// </summary>
-        /// <param name="callback">A callback to execute</param>
-        /// <param name="state">
-        /// The context object of the work item. Used for passing arguments to the work item. 
-        /// </param>
-        /// <param name="postExecuteWorkItemCallback">
-        /// A delegate to call after the callback completion
-        /// </param>
-        /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
-        /// <returns>Returns a work item result</returns>
-        IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute);
-
-        /// <summary>
-        /// Queue a work item
-        /// </summary>
-        /// <param name="callback">A callback to execute</param>
-        /// <param name="state">
-        /// The context object of the work item. Used for passing arguments to the work item. 
-        /// </param>
-        /// <param name="postExecuteWorkItemCallback">
-        /// A delegate to call after the callback completion
-        /// </param>
-        /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
-        /// <param name="workItemPriority">The work item priority</param>
-        /// <returns>Returns a work item result</returns>
-        IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute, WorkItemPriority workItemPriority);
-
-        /// <summary>
-        /// Queue a work item
-        /// </summary>
-        /// <param name="workItemInfo">Work item info</param>
-        /// <param name="callback">A callback to execute</param>
-        /// <returns>Returns a work item result</returns>
-        IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback);
-
-        /// <summary>
-        /// Queue a work item
-        /// </summary>
-        /// <param name="workItemInfo">Work item information</param>
-        /// <param name="callback">A callback to execute</param>
-        /// <param name="state">
-        /// The context object of the work item. Used for passing arguments to the work item. 
-        /// </param>
-        /// <returns>Returns a work item result</returns>
-        IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state);
-
-        #endregion
-
-        #region QueueWorkItem(Action<...>)
-
-        /// <summary>
-        /// Queue a work item.
-        /// </summary>
-        /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
-        IWorkItemResult QueueWorkItem(Action action);
-
-        /// <summary>
-        /// Queue a work item.
-        /// </summary>
-        /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
-        IWorkItemResult QueueWorkItem (Action action, WorkItemPriority priority);
-
-        /// <summary>
-        /// Queue a work item.
-        /// </summary>
-        /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
-        IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg, WorkItemPriority priority);
-
-        /// <summary>
-        /// Queue a work item.
-        /// </summary>
-        /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
-        IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg);
-
-        /// <summary>
-        /// Queue a work item.
-        /// </summary>
-        /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
-        IWorkItemResult QueueWorkItem<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2);
-
-        /// <summary>
-        /// Queue a work item.
-        /// </summary>
-        /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
-        IWorkItemResult QueueWorkItem<T1, T2> (Action<T1, T2> action, T1 arg1, T2 arg2, WorkItemPriority priority);
-
-        /// <summary>
-        /// Queue a work item.
-        /// </summary>
-        /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
-        IWorkItemResult QueueWorkItem<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3);
-
-        /// <summary>
-        /// Queue a work item.
-        /// </summary>
-        /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
-        IWorkItemResult QueueWorkItem<T1, T2, T3> (Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3, WorkItemPriority priority);
-
-        /// <summary>
-        /// Queue a work item.
-        /// </summary>
-        /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
-        IWorkItemResult QueueWorkItem<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4);
-
-        /// <summary>
-        /// Queue a work item.
-        /// </summary>
-        /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
-        IWorkItemResult QueueWorkItem<T1, T2, T3, T4> (Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, WorkItemPriority priority);
-
-        #endregion
-
-        #region QueueWorkItem(Func<...>)
-
-        /// <summary>
-        /// Queue a work item.
-        /// </summary>
-        /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object. 
-        /// its GetResult() returns a TResult object</returns>
-        IWorkItemResult<TResult> QueueWorkItem<TResult>(Func<TResult> func);
-
-        /// <summary>
-        /// Queue a work item.
-        /// </summary>
-        /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object. 
-        /// its GetResult() returns a TResult object</returns>
-        IWorkItemResult<TResult> QueueWorkItem<T, TResult>(Func<T, TResult> func, T arg);
-
-        /// <summary>
-        /// Queue a work item.
-        /// </summary>
-        /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object. 
-        /// its GetResult() returns a TResult object</returns>
-        IWorkItemResult<TResult> QueueWorkItem<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 arg1, T2 arg2);
-
-        /// <summary>
-        /// Queue a work item.
-        /// </summary>
-        /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object. 
-        /// its GetResult() returns a TResult object</returns>
-        IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> func, T1 arg1, T2 arg2, T3 arg3);
-
-        /// <summary>
-        /// Queue a work item.
-        /// </summary>
-        /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object. 
-        /// its GetResult() returns a TResult object</returns>
-        IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, T4, TResult>(Func<T1, T2, T3, T4, TResult> func, T1 arg1, T2 arg2, T3 arg3, T4 arg4);
-
-        #endregion
-    }
-
-	#endregion
-
-	#region CallToPostExecute enumerator
-
-	[Flags]
-	public enum CallToPostExecute
-	{
-        /// <summary>
-        /// Never call to the PostExecute call back
-        /// </summary>
-		Never                    = 0x00,
-
-        /// <summary>
-        /// Call to the PostExecute only when the work item is cancelled
-        /// </summary>
-		WhenWorkItemCanceled     = 0x01,
-
-        /// <summary>
-        /// Call to the PostExecute only when the work item is not cancelled
-        /// </summary>
-		WhenWorkItemNotCanceled  = 0x02,
-
-        /// <summary>
-        /// Always call to the PostExecute
-        /// </summary>
-		Always                   = WhenWorkItemCanceled | WhenWorkItemNotCanceled,
-	}
-
-	#endregion
-
-	#region IWorkItemResult interface
-
-    /// <summary>
-    /// The common interface of IWorkItemResult and IWorkItemResult&lt;T&gt;
-    /// </summary>
-    public interface IWaitableResult
-    {
-        /// <summary>
-        /// This method intent is for internal use.
-        /// </summary>
-        /// <returns></returns>
-        IWorkItemResult GetWorkItemResult();
-
-        /// <summary>
-        /// This method intent is for internal use.
-        /// </summary>
-        /// <returns></returns>
-        IWorkItemResult<TResult> GetWorkItemResultT<TResult>();
-    }
-
-    /// <summary>
-    /// IWorkItemResult interface.
-    /// Created when a WorkItemCallback work item is queued.
-    /// </summary>
-    public interface IWorkItemResult : IWorkItemResult<object>
-    {
-    }
-
-	/// <summary>
-    /// IWorkItemResult&lt;TResult&gt; interface.
-    /// Created when a Func&lt;TResult&gt; work item is queued.
-	/// </summary>
-    public interface IWorkItemResult<TResult> : IWaitableResult
-	{
-		/// <summary>
-		/// Get the result of the work item.
-		/// If the work item didn't run yet then the caller waits.
-		/// </summary>
-		/// <returns>The result of the work item</returns>
-        TResult GetResult();
-
-		/// <summary>
-		/// Get the result of the work item.
-		/// If the work item didn't run yet then the caller waits until timeout.
-		/// </summary>
-		/// <returns>The result of the work item</returns>
-		/// On timeout throws WorkItemTimeoutException
-        TResult GetResult(
-			int millisecondsTimeout,
-			bool exitContext);
-
-		/// <summary>
-		/// Get the result of the work item.
-		/// If the work item didn't run yet then the caller waits until timeout.
-		/// </summary>
-		/// <returns>The result of the work item</returns>
-		/// On timeout throws WorkItemTimeoutException
-        TResult GetResult(			
-			TimeSpan timeout,
-			bool exitContext);
-
-		/// <summary>
-		/// Get the result of the work item.
-		/// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
-		/// </summary>
-		/// <param name="millisecondsTimeout">Timeout in milliseconds, or -1 for infinite</param>
-		/// <param name="exitContext">
-		/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 
-		/// </param>
-		/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the blocking if needed</param>
-		/// <returns>The result of the work item</returns>
-		/// On timeout throws WorkItemTimeoutException
-		/// On cancel throws WorkItemCancelException
-        TResult GetResult(			
-			int millisecondsTimeout,
-			bool exitContext,
-			WaitHandle cancelWaitHandle);
-
-		/// <summary>
-		/// Get the result of the work item.
-		/// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
-		/// </summary>
-		/// <returns>The result of the work item</returns>
-		/// On timeout throws WorkItemTimeoutException
-		/// On cancel throws WorkItemCancelException
-        TResult GetResult(			
-			TimeSpan timeout,
-			bool exitContext,
-			WaitHandle cancelWaitHandle);
-
-		/// <summary>
-		/// Get the result of the work item.
-		/// If the work item didn't run yet then the caller waits.
-		/// </summary>
-		/// <param name="e">Filled with the exception if one was thrown</param>
-		/// <returns>The result of the work item</returns>
-        TResult GetResult(out Exception e);
-
-		/// <summary>
-		/// Get the result of the work item.
-		/// If the work item didn't run yet then the caller waits until timeout.
-		/// </summary>
-		/// <param name="millisecondsTimeout"></param>
-		/// <param name="exitContext"></param>
-		/// <param name="e">Filled with the exception if one was thrown</param>
-		/// <returns>The result of the work item</returns>
-		/// On timeout throws WorkItemTimeoutException
-        TResult GetResult(
-			int millisecondsTimeout,
-			bool exitContext,
-			out Exception e);
-
-		/// <summary>
-		/// Get the result of the work item.
-		/// If the work item didn't run yet then the caller waits until timeout.
-		/// </summary>
-		/// <param name="exitContext"></param>
-		/// <param name="e">Filled with the exception if one was thrown</param>
-		/// <param name="timeout"></param>
-		/// <returns>The result of the work item</returns>
-		/// On timeout throws WorkItemTimeoutException
-        TResult GetResult(			
-			TimeSpan timeout,
-			bool exitContext,
-			out Exception e);
-
-		/// <summary>
-		/// Get the result of the work item.
-		/// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
-		/// </summary>
-		/// <param name="millisecondsTimeout">Timeout in milliseconds, or -1 for infinite</param>
-		/// <param name="exitContext">
-		/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 
-		/// </param>
-		/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the blocking if needed</param>
-		/// <param name="e">Filled with the exception if one was thrown</param>
-		/// <returns>The result of the work item</returns>
-		/// On timeout throws WorkItemTimeoutException
-		/// On cancel throws WorkItemCancelException
-        TResult GetResult(			
-			int millisecondsTimeout,
-			bool exitContext,
-			WaitHandle cancelWaitHandle,
-			out Exception e);
-
-		/// <summary>
-		/// Get the result of the work item.
-		/// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
-		/// </summary>
-		/// <returns>The result of the work item</returns>
-		/// <param name="cancelWaitHandle"></param>
-		/// <param name="e">Filled with the exception if one was thrown</param>
-		/// <param name="timeout"></param>
-		/// <param name="exitContext"></param>
-		/// On timeout throws WorkItemTimeoutException
-		/// On cancel throws WorkItemCancelException
-        TResult GetResult(			
-			TimeSpan timeout,
-			bool exitContext,
-			WaitHandle cancelWaitHandle,
-			out Exception e);
-
-		/// <summary>
-		/// Gets an indication whether the asynchronous operation has completed.
-		/// </summary>
-		bool IsCompleted { get; }
-
-		/// <summary>
-		/// Gets an indication whether the asynchronous operation has been canceled.
-		/// </summary>
-		bool IsCanceled { get; }
-
-		/// <summary>
-		/// Gets the user-defined object that contains context data 
-        /// for the work item method.
-		/// </summary>
-		object State { get; }
-
-		/// <summary>
-        /// Same as Cancel(false).
-		/// </summary>
-        bool Cancel();
-
-        /// <summary>
-        /// Cancel the work item execution.
-        /// If the work item is in the queue then it won't execute
-        /// If the work item is completed, it will remain completed
-        /// If the work item is in progress then the user can check the SmartThreadPool.IsWorkItemCanceled
-        ///   property to check if the work item has been cancelled. If the abortExecution is set to true then
-        ///   the Smart Thread Pool will send an AbortException to the running thread to stop the execution 
-        ///   of the work item. When an in progress work item is canceled its GetResult will throw WorkItemCancelException.
-        /// If the work item is already cancelled it will remain cancelled
-        /// </summary>
-        /// <param name="abortExecution">When true send an AbortException to the executing thread.</param>
-        /// <returns>Returns true if the work item was not completed, otherwise false.</returns>
-        bool Cancel(bool abortExecution);
-
-		/// <summary>
-		/// Get the work item's priority
-		/// </summary>
-		WorkItemPriority WorkItemPriority { get; }
-
-		/// <summary>
-		/// Return the result, same as GetResult()
-		/// </summary>
-        TResult Result { get; }
-
-		/// <summary>
-		/// Returns the exception if occured otherwise returns null.
-		/// </summary>
-		object Exception { get; }
-	}
-
-	#endregion
-
-    #region .NET 3.5
-
-    // All these delegate are built-in .NET 3.5
-    // Comment/Remove them when compiling to .NET 3.5 to avoid ambiguity.
-
-    public delegate void Action();
-    public delegate void Action<T1, T2>(T1 arg1, T2 arg2);
-    public delegate void Action<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3);
-    public delegate void Action<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
-
-    public delegate TResult Func<TResult>();
-    public delegate TResult Func<T, TResult>(T arg1);
-    public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
-    public delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
-    public delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
-
-    #endregion
-}
+using System;
+using System.Threading;
+
+namespace Amib.Threading
+{
+	#region Delegates
+
+	/// <summary>
+	/// A delegate that represents the method to run as the work item
+	/// </summary>
+	/// <param name="state">A state object for the method to run</param>
+	public delegate object WorkItemCallback(object state);
+
+	/// <summary>
+	/// A delegate to call after the WorkItemCallback completed
+	/// </summary>
+	/// <param name="wir">The work item result object</param>
+    public delegate void PostExecuteWorkItemCallback(IWorkItemResult wir);
+
+    /// <summary>
+    /// A delegate to call after the WorkItemCallback completed
+    /// </summary>
+    /// <param name="wir">The work item result object</param>
+    public delegate void PostExecuteWorkItemCallback<TResult>(IWorkItemResult<TResult> wir);
+
+	/// <summary>
+	/// A delegate to call when a WorkItemsGroup becomes idle
+	/// </summary>
+	/// <param name="workItemsGroup">A reference to the WorkItemsGroup that became idle</param>
+	public delegate void WorkItemsGroupIdleHandler(IWorkItemsGroup workItemsGroup);
+
+    /// <summary>
+    /// A delegate to call after a thread is created, but before 
+    /// it's first use.
+    /// </summary>
+    public delegate void ThreadInitializationHandler();
+
+    /// <summary>
+    /// A delegate to call when a thread is about to exit, after 
+    /// it is no longer belong to the pool.
+    /// </summary>
+    public delegate void ThreadTerminationHandler();
+
+	#endregion
+
+	#region WorkItem Priority
+
+    /// <summary>
+    /// Defines the availeable priorities of a work item.
+    /// The higher the priority a work item has, the sooner
+    /// it will be executed.
+    /// </summary>
+	public enum WorkItemPriority
+	{
+		Lowest,
+		BelowNormal,
+		Normal,
+		AboveNormal,
+		Highest,
+	}
+
+	#endregion
+
+	#region IWorkItemsGroup interface 
+
+	/// <summary>
+	/// IWorkItemsGroup interface
+    /// Created by SmartThreadPool.CreateWorkItemsGroup()
+	/// </summary>
+	public interface IWorkItemsGroup
+	{
+		/// <summary>
+		/// Get/Set the name of the WorkItemsGroup
+		/// </summary>
+		string Name { get; set; }
+
+        /// <summary>
+        /// Get/Set the maximum number of workitem that execute cocurrency on the thread pool
+        /// </summary>
+        int Concurrency { get; set; }
+
+        /// <summary>
+        /// Get the number of work items waiting in the queue.
+        /// </summary>
+        int WaitingCallbacks { get; }
+
+        /// <summary>
+        /// Get an array with all the state objects of the currently running items.
+        /// The array represents a snap shot and impact performance.
+        /// </summary>
+        object[] GetStates();
+
+        /// <summary>
+        /// Get the WorkItemsGroup start information
+        /// </summary>
+        WIGStartInfo WIGStartInfo { get; }
+
+        /// <summary>
+        /// Starts to execute work items
+        /// </summary>
+        void Start();
+
+        /// <summary>
+        /// Cancel all the work items.
+        /// Same as Cancel(false)
+        /// </summary>
+        void Cancel();
+
+        /// <summary>
+        /// Cancel all work items using thread abortion
+        /// </summary>
+        /// <param name="abortExecution">True to stop work items by raising ThreadAbortException</param>
+        void Cancel(bool abortExecution);
+
+        /// <summary>
+        /// Wait for all work item to complete.
+        /// </summary>
+		void WaitForIdle();
+
+        /// <summary>
+        /// Wait for all work item to complete, until timeout expired
+        /// </summary>
+        /// <param name="timeout">How long to wait for the work items to complete</param>
+        /// <returns>Returns true if work items completed within the timeout, otherwise false.</returns>
+		bool WaitForIdle(TimeSpan timeout);
+
+        /// <summary>
+        /// Wait for all work item to complete, until timeout expired
+        /// </summary>
+        /// <param name="millisecondsTimeout">How long to wait for the work items to complete in milliseconds</param>
+        /// <returns>Returns true if work items completed within the timeout, otherwise false.</returns>
+        bool WaitForIdle(int millisecondsTimeout);
+
+        /// <summary>
+        /// IsIdle is true when there are no work items running or queued.
+        /// </summary>
+        bool IsIdle { get; }
+
+        /// <summary>
+        /// This event is fired when all work items are completed.
+        /// (When IsIdle changes to true)
+        /// This event only work on WorkItemsGroup. On SmartThreadPool
+        /// it throws the NotImplementedException.
+        /// </summary>
+        event WorkItemsGroupIdleHandler OnIdle;
+
+        #region QueueWorkItem
+
+        /// <summary>
+        /// Queue a work item
+        /// </summary>
+        /// <param name="callback">A callback to execute</param>
+        /// <returns>Returns a work item result</returns>        
+        IWorkItemResult QueueWorkItem(WorkItemCallback callback);
+
+        /// <summary>
+        /// Queue a work item
+        /// </summary>
+        /// <param name="callback">A callback to execute</param>
+        /// <param name="workItemPriority">The priority of the work item</param>
+        /// <returns>Returns a work item result</returns>
+        IWorkItemResult QueueWorkItem(WorkItemCallback callback, WorkItemPriority workItemPriority);
+
+        /// <summary>
+        /// Queue a work item
+        /// </summary>
+        /// <param name="callback">A callback to execute</param>
+        /// <param name="state">
+        /// The context object of the work item. Used for passing arguments to the work item. 
+        /// </param>
+        /// <returns>Returns a work item result</returns>
+        IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state);
+
+        /// <summary>
+        /// Queue a work item
+        /// </summary>
+        /// <param name="callback">A callback to execute</param>
+        /// <param name="state">
+        /// The context object of the work item. Used for passing arguments to the work item. 
+        /// </param>
+        /// <param name="workItemPriority">The work item priority</param>
+        /// <returns>Returns a work item result</returns>
+        IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, WorkItemPriority workItemPriority);
+
+        /// <summary>
+        /// Queue a work item
+        /// </summary>
+        /// <param name="callback">A callback to execute</param>
+        /// <param name="state">
+        /// The context object of the work item. Used for passing arguments to the work item. 
+        /// </param>
+        /// <param name="postExecuteWorkItemCallback">
+        /// A delegate to call after the callback completion
+        /// </param>
+        /// <returns>Returns a work item result</returns>
+        IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback);
+
+        /// <summary>
+        /// Queue a work item
+        /// </summary>
+        /// <param name="callback">A callback to execute</param>
+        /// <param name="state">
+        /// The context object of the work item. Used for passing arguments to the work item. 
+        /// </param>
+        /// <param name="postExecuteWorkItemCallback">
+        /// A delegate to call after the callback completion
+        /// </param>
+        /// <param name="workItemPriority">The work item priority</param>
+        /// <returns>Returns a work item result</returns>
+        IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, WorkItemPriority workItemPriority);
+
+        /// <summary>
+        /// Queue a work item
+        /// </summary>
+        /// <param name="callback">A callback to execute</param>
+        /// <param name="state">
+        /// The context object of the work item. Used for passing arguments to the work item. 
+        /// </param>
+        /// <param name="postExecuteWorkItemCallback">
+        /// A delegate to call after the callback completion
+        /// </param>
+        /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
+        /// <returns>Returns a work item result</returns>
+        IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute);
+
+        /// <summary>
+        /// Queue a work item
+        /// </summary>
+        /// <param name="callback">A callback to execute</param>
+        /// <param name="state">
+        /// The context object of the work item. Used for passing arguments to the work item. 
+        /// </param>
+        /// <param name="postExecuteWorkItemCallback">
+        /// A delegate to call after the callback completion
+        /// </param>
+        /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
+        /// <param name="workItemPriority">The work item priority</param>
+        /// <returns>Returns a work item result</returns>
+        IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute, WorkItemPriority workItemPriority);
+
+        /// <summary>
+        /// Queue a work item
+        /// </summary>
+        /// <param name="workItemInfo">Work item info</param>
+        /// <param name="callback">A callback to execute</param>
+        /// <returns>Returns a work item result</returns>
+        IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback);
+
+        /// <summary>
+        /// Queue a work item
+        /// </summary>
+        /// <param name="workItemInfo">Work item information</param>
+        /// <param name="callback">A callback to execute</param>
+        /// <param name="state">
+        /// The context object of the work item. Used for passing arguments to the work item. 
+        /// </param>
+        /// <returns>Returns a work item result</returns>
+        IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state);
+
+        #endregion
+
+        #region QueueWorkItem(Action<...>)
+
+        /// <summary>
+        /// Queue a work item.
+        /// </summary>
+        /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
+        IWorkItemResult QueueWorkItem(Action action);
+
+        /// <summary>
+        /// Queue a work item.
+        /// </summary>
+        /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
+        IWorkItemResult QueueWorkItem (Action action, WorkItemPriority priority);
+
+        /// <summary>
+        /// Queue a work item.
+        /// </summary>
+        /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
+        IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg, WorkItemPriority priority);
+
+        /// <summary>
+        /// Queue a work item.
+        /// </summary>
+        /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
+        IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg);
+
+        /// <summary>
+        /// Queue a work item.
+        /// </summary>
+        /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
+        IWorkItemResult QueueWorkItem<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2);
+
+        /// <summary>
+        /// Queue a work item.
+        /// </summary>
+        /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
+        IWorkItemResult QueueWorkItem<T1, T2> (Action<T1, T2> action, T1 arg1, T2 arg2, WorkItemPriority priority);
+
+        /// <summary>
+        /// Queue a work item.
+        /// </summary>
+        /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
+        IWorkItemResult QueueWorkItem<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3);
+
+        /// <summary>
+        /// Queue a work item.
+        /// </summary>
+        /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
+        IWorkItemResult QueueWorkItem<T1, T2, T3> (Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3, WorkItemPriority priority);
+
+        /// <summary>
+        /// Queue a work item.
+        /// </summary>
+        /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
+        IWorkItemResult QueueWorkItem<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4);
+
+        /// <summary>
+        /// Queue a work item.
+        /// </summary>
+        /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
+        IWorkItemResult QueueWorkItem<T1, T2, T3, T4> (Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, WorkItemPriority priority);
+
+        #endregion
+
+        #region QueueWorkItem(Func<...>)
+
+        /// <summary>
+        /// Queue a work item.
+        /// </summary>
+        /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object. 
+        /// its GetResult() returns a TResult object</returns>
+        IWorkItemResult<TResult> QueueWorkItem<TResult>(Func<TResult> func);
+
+        /// <summary>
+        /// Queue a work item.
+        /// </summary>
+        /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object. 
+        /// its GetResult() returns a TResult object</returns>
+        IWorkItemResult<TResult> QueueWorkItem<T, TResult>(Func<T, TResult> func, T arg);
+
+        /// <summary>
+        /// Queue a work item.
+        /// </summary>
+        /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object. 
+        /// its GetResult() returns a TResult object</returns>
+        IWorkItemResult<TResult> QueueWorkItem<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 arg1, T2 arg2);
+
+        /// <summary>
+        /// Queue a work item.
+        /// </summary>
+        /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object. 
+        /// its GetResult() returns a TResult object</returns>
+        IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> func, T1 arg1, T2 arg2, T3 arg3);
+
+        /// <summary>
+        /// Queue a work item.
+        /// </summary>
+        /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object. 
+        /// its GetResult() returns a TResult object</returns>
+        IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, T4, TResult>(Func<T1, T2, T3, T4, TResult> func, T1 arg1, T2 arg2, T3 arg3, T4 arg4);
+
+        #endregion
+    }
+
+	#endregion
+
+	#region CallToPostExecute enumerator
+
+	[Flags]
+	public enum CallToPostExecute
+	{
+        /// <summary>
+        /// Never call to the PostExecute call back
+        /// </summary>
+		Never                    = 0x00,
+
+        /// <summary>
+        /// Call to the PostExecute only when the work item is cancelled
+        /// </summary>
+		WhenWorkItemCanceled     = 0x01,
+
+        /// <summary>
+        /// Call to the PostExecute only when the work item is not cancelled
+        /// </summary>
+		WhenWorkItemNotCanceled  = 0x02,
+
+        /// <summary>
+        /// Always call to the PostExecute
+        /// </summary>
+		Always                   = WhenWorkItemCanceled | WhenWorkItemNotCanceled,
+	}
+
+	#endregion
+
+	#region IWorkItemResult interface
+
+    /// <summary>
+    /// The common interface of IWorkItemResult and IWorkItemResult&lt;T&gt;
+    /// </summary>
+    public interface IWaitableResult
+    {
+        /// <summary>
+        /// This method intent is for internal use.
+        /// </summary>
+        /// <returns></returns>
+        IWorkItemResult GetWorkItemResult();
+
+        /// <summary>
+        /// This method intent is for internal use.
+        /// </summary>
+        /// <returns></returns>
+        IWorkItemResult<TResult> GetWorkItemResultT<TResult>();
+    }
+
+    /// <summary>
+    /// IWorkItemResult interface.
+    /// Created when a WorkItemCallback work item is queued.
+    /// </summary>
+    public interface IWorkItemResult : IWorkItemResult<object>
+    {
+    }
+
+	/// <summary>
+    /// IWorkItemResult&lt;TResult&gt; interface.
+    /// Created when a Func&lt;TResult&gt; work item is queued.
+	/// </summary>
+    public interface IWorkItemResult<TResult> : IWaitableResult
+	{
+		/// <summary>
+		/// Get the result of the work item.
+		/// If the work item didn't run yet then the caller waits.
+		/// </summary>
+		/// <returns>The result of the work item</returns>
+        TResult GetResult();
+
+		/// <summary>
+		/// Get the result of the work item.
+		/// If the work item didn't run yet then the caller waits until timeout.
+		/// </summary>
+		/// <returns>The result of the work item</returns>
+		/// On timeout throws WorkItemTimeoutException
+        TResult GetResult(
+			int millisecondsTimeout,
+			bool exitContext);
+
+		/// <summary>
+		/// Get the result of the work item.
+		/// If the work item didn't run yet then the caller waits until timeout.
+		/// </summary>
+		/// <returns>The result of the work item</returns>
+		/// On timeout throws WorkItemTimeoutException
+        TResult GetResult(			
+			TimeSpan timeout,
+			bool exitContext);
+
+		/// <summary>
+		/// Get the result of the work item.
+		/// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
+		/// </summary>
+		/// <param name="millisecondsTimeout">Timeout in milliseconds, or -1 for infinite</param>
+		/// <param name="exitContext">
+		/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 
+		/// </param>
+		/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the blocking if needed</param>
+		/// <returns>The result of the work item</returns>
+		/// On timeout throws WorkItemTimeoutException
+		/// On cancel throws WorkItemCancelException
+        TResult GetResult(			
+			int millisecondsTimeout,
+			bool exitContext,
+			WaitHandle cancelWaitHandle);
+
+		/// <summary>
+		/// Get the result of the work item.
+		/// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
+		/// </summary>
+		/// <returns>The result of the work item</returns>
+		/// On timeout throws WorkItemTimeoutException
+		/// On cancel throws WorkItemCancelException
+        TResult GetResult(			
+			TimeSpan timeout,
+			bool exitContext,
+			WaitHandle cancelWaitHandle);
+
+		/// <summary>
+		/// Get the result of the work item.
+		/// If the work item didn't run yet then the caller waits.
+		/// </summary>
+		/// <param name="e">Filled with the exception if one was thrown</param>
+		/// <returns>The result of the work item</returns>
+        TResult GetResult(out Exception e);
+
+		/// <summary>
+		/// Get the result of the work item.
+		/// If the work item didn't run yet then the caller waits until timeout.
+		/// </summary>
+		/// <param name="millisecondsTimeout"></param>
+		/// <param name="exitContext"></param>
+		/// <param name="e">Filled with the exception if one was thrown</param>
+		/// <returns>The result of the work item</returns>
+		/// On timeout throws WorkItemTimeoutException
+        TResult GetResult(
+			int millisecondsTimeout,
+			bool exitContext,
+			out Exception e);
+
+		/// <summary>
+		/// Get the result of the work item.
+		/// If the work item didn't run yet then the caller waits until timeout.
+		/// </summary>
+		/// <param name="exitContext"></param>
+		/// <param name="e">Filled with the exception if one was thrown</param>
+		/// <param name="timeout"></param>
+		/// <returns>The result of the work item</returns>
+		/// On timeout throws WorkItemTimeoutException
+        TResult GetResult(			
+			TimeSpan timeout,
+			bool exitContext,
+			out Exception e);
+
+		/// <summary>
+		/// Get the result of the work item.
+		/// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
+		/// </summary>
+		/// <param name="millisecondsTimeout">Timeout in milliseconds, or -1 for infinite</param>
+		/// <param name="exitContext">
+		/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 
+		/// </param>
+		/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the blocking if needed</param>
+		/// <param name="e">Filled with the exception if one was thrown</param>
+		/// <returns>The result of the work item</returns>
+		/// On timeout throws WorkItemTimeoutException
+		/// On cancel throws WorkItemCancelException
+        TResult GetResult(			
+			int millisecondsTimeout,
+			bool exitContext,
+			WaitHandle cancelWaitHandle,
+			out Exception e);
+
+		/// <summary>
+		/// Get the result of the work item.
+		/// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
+		/// </summary>
+		/// <returns>The result of the work item</returns>
+		/// <param name="cancelWaitHandle"></param>
+		/// <param name="e">Filled with the exception if one was thrown</param>
+		/// <param name="timeout"></param>
+		/// <param name="exitContext"></param>
+		/// On timeout throws WorkItemTimeoutException
+		/// On cancel throws WorkItemCancelException
+        TResult GetResult(			
+			TimeSpan timeout,
+			bool exitContext,
+			WaitHandle cancelWaitHandle,
+			out Exception e);
+
+		/// <summary>
+		/// Gets an indication whether the asynchronous operation has completed.
+		/// </summary>
+		bool IsCompleted { get; }
+
+		/// <summary>
+		/// Gets an indication whether the asynchronous operation has been canceled.
+		/// </summary>
+		bool IsCanceled { get; }
+
+		/// <summary>
+		/// Gets the user-defined object that contains context data 
+        /// for the work item method.
+		/// </summary>
+		object State { get; }
+
+		/// <summary>
+        /// Same as Cancel(false).
+		/// </summary>
+        bool Cancel();
+
+        /// <summary>
+        /// Cancel the work item execution.
+        /// If the work item is in the queue then it won't execute
+        /// If the work item is completed, it will remain completed
+        /// If the work item is in progress then the user can check the SmartThreadPool.IsWorkItemCanceled
+        ///   property to check if the work item has been cancelled. If the abortExecution is set to true then
+        ///   the Smart Thread Pool will send an AbortException to the running thread to stop the execution 
+        ///   of the work item. When an in progress work item is canceled its GetResult will throw WorkItemCancelException.
+        /// If the work item is already cancelled it will remain cancelled
+        /// </summary>
+        /// <param name="abortExecution">When true send an AbortException to the executing thread.</param>
+        /// <returns>Returns true if the work item was not completed, otherwise false.</returns>
+        bool Cancel(bool abortExecution);
+
+		/// <summary>
+		/// Get the work item's priority
+		/// </summary>
+		WorkItemPriority WorkItemPriority { get; }
+
+		/// <summary>
+		/// Return the result, same as GetResult()
+		/// </summary>
+        TResult Result { get; }
+
+		/// <summary>
+		/// Returns the exception if occured otherwise returns null.
+		/// </summary>
+		object Exception { get; }
+	}
+
+	#endregion
+
+    #region .NET 3.5
+
+    // All these delegate are built-in .NET 3.5
+    // Comment/Remove them when compiling to .NET 3.5 to avoid ambiguity.
+
+    public delegate void Action();
+    public delegate void Action<T1, T2>(T1 arg1, T2 arg2);
+    public delegate void Action<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3);
+    public delegate void Action<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
+
+    public delegate TResult Func<TResult>();
+    public delegate TResult Func<T, TResult>(T arg1);
+    public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
+    public delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
+    public delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
+
+    #endregion
+}

+ 27 - 27
ThirdParty/SmartThreadPool/InternalInterfaces.cs

@@ -1,27 +1,27 @@
-
-namespace Amib.Threading.Internal
-{
-    /// <summary>
-    /// An internal delegate to call when the WorkItem starts or completes
-    /// </summary>
-    internal delegate void WorkItemStateCallback(WorkItem workItem);
-
-    internal interface IInternalWorkItemResult
-    {
-        event WorkItemStateCallback OnWorkItemStarted;
-        event WorkItemStateCallback OnWorkItemCompleted;
-    }
-
-    internal interface IInternalWaitableResult
-    {
-        /// <summary>
-        /// This method is intent for internal use.
-        /// </summary>   
-        IWorkItemResult GetWorkItemResult();
-    }
-
-    public interface IHasWorkItemPriority
-    {
-        WorkItemPriority WorkItemPriority { get; }
-    }
-}
+
+namespace Amib.Threading.Internal
+{
+    /// <summary>
+    /// An internal delegate to call when the WorkItem starts or completes
+    /// </summary>
+    internal delegate void WorkItemStateCallback(WorkItem workItem);
+
+    internal interface IInternalWorkItemResult
+    {
+        event WorkItemStateCallback OnWorkItemStarted;
+        event WorkItemStateCallback OnWorkItemCompleted;
+    }
+
+    internal interface IInternalWaitableResult
+    {
+        /// <summary>
+        /// This method is intent for internal use.
+        /// </summary>   
+        IWorkItemResult GetWorkItemResult();
+    }
+
+    public interface IHasWorkItemPriority
+    {
+        WorkItemPriority WorkItemPriority { get; }
+    }
+}

+ 239 - 239
ThirdParty/SmartThreadPool/PriorityQueue.cs

@@ -1,239 +1,239 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics;
-
-namespace Amib.Threading.Internal
-{
-	#region PriorityQueue class
-
-	/// <summary>
-	/// PriorityQueue class
-	/// This class is not thread safe because we use external lock
-	/// </summary>
-	public sealed class PriorityQueue : IEnumerable
-	{
-		#region Private members
-
-		/// <summary>
-		/// The number of queues, there is one for each type of priority
-		/// </summary>
-		private const int _queuesCount = WorkItemPriority.Highest-WorkItemPriority.Lowest+1;
-
-		/// <summary>
-		/// Work items queues. There is one for each type of priority
-		/// </summary>
-        private readonly LinkedList<IHasWorkItemPriority>[] _queues = new LinkedList<IHasWorkItemPriority>[_queuesCount];
-
-		/// <summary>
-		/// The total number of work items within the queues 
-		/// </summary>
-		private int _workItemsCount;
-
-		/// <summary>
-		/// Use with IEnumerable interface
-		/// </summary>
-		private int _version;
-
-		#endregion
-
-		#region Contructor
-
-		public PriorityQueue()
-		{
-			for(int i = 0; i < _queues.Length; ++i)
-			{
-                _queues[i] = new LinkedList<IHasWorkItemPriority>();
-			}
-		}
-
-		#endregion
-
-		#region Methods
-
-		/// <summary>
-		/// Enqueue a work item.
-		/// </summary>
-		/// <param name="workItem">A work item</param>
-		public void Enqueue(IHasWorkItemPriority workItem)
-		{
-			Debug.Assert(null != workItem);
-
-			int queueIndex = _queuesCount-(int)workItem.WorkItemPriority-1;
-			Debug.Assert(queueIndex >= 0);
-			Debug.Assert(queueIndex < _queuesCount);
-
-			_queues[queueIndex].AddLast(workItem);
-			++_workItemsCount;
-			++_version;
-		}
-
-		/// <summary>
-		/// Dequeque a work item.
-		/// </summary>
-		/// <returns>Returns the next work item</returns>
-		public IHasWorkItemPriority Dequeue()
-		{
-			IHasWorkItemPriority workItem = null;
-
-			if(_workItemsCount > 0)
-			{
-				int queueIndex = GetNextNonEmptyQueue(-1);
-				Debug.Assert(queueIndex >= 0);
-                workItem = _queues[queueIndex].First.Value;
-				_queues[queueIndex].RemoveFirst();
-				Debug.Assert(null != workItem);
-				--_workItemsCount;
-				++_version;
-			}
-
-			return workItem;
-		}
-
-		/// <summary>
-		/// Find the next non empty queue starting at queue queueIndex+1
-		/// </summary>
-		/// <param name="queueIndex">The index-1 to start from</param>
-		/// <returns>
-		/// The index of the next non empty queue or -1 if all the queues are empty
-		/// </returns>
-		private int GetNextNonEmptyQueue(int queueIndex)
-		{
-			for(int i = queueIndex+1; i < _queuesCount; ++i)
-			{
-				if(_queues[i].Count > 0)
-				{
-					return i;
-				}
-			}
-			return -1;
-		}
-
-		/// <summary>
-		/// The number of work items 
-		/// </summary>
-		public int Count
-		{
-			get
-			{
-				return _workItemsCount;
-			}
-		}
-
-		/// <summary>
-		/// Clear all the work items 
-		/// </summary>
-		public void Clear()
-		{
-			if (_workItemsCount > 0)
-			{
-				foreach(LinkedList<IHasWorkItemPriority> queue in _queues)
-				{
-					queue.Clear();
-				}
-				_workItemsCount = 0;
-				++_version;
-			}
-		}
-
-		#endregion
-
-		#region IEnumerable Members
-
-		/// <summary>
-		/// Returns an enumerator to iterate over the work items
-		/// </summary>
-		/// <returns>Returns an enumerator</returns>
-		public IEnumerator GetEnumerator()
-		{
-			return new PriorityQueueEnumerator(this);
-		}
-
-		#endregion
-
-		#region PriorityQueueEnumerator
-
-		/// <summary>
-		/// The class the implements the enumerator
-		/// </summary>
-		private class PriorityQueueEnumerator : IEnumerator
-		{
-			private readonly PriorityQueue _priorityQueue;
-			private int _version;
-			private int _queueIndex;
-			private IEnumerator _enumerator;
-
-			public PriorityQueueEnumerator(PriorityQueue priorityQueue)
-			{
-				_priorityQueue = priorityQueue;
-				_version = _priorityQueue._version;
-				_queueIndex = _priorityQueue.GetNextNonEmptyQueue(-1);
-				if (_queueIndex >= 0)
-				{
-					_enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator();
-				}
-				else
-				{
-					_enumerator = null;
-				}
-			}
-
-			#region IEnumerator Members
-
-			public void Reset()
-			{
-				_version = _priorityQueue._version;
-				_queueIndex = _priorityQueue.GetNextNonEmptyQueue(-1);
-				if (_queueIndex >= 0)
-				{
-					_enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator();
-				}
-				else
-				{
-					_enumerator = null;
-				}
-			}
-
-			public object Current
-			{
-				get
-				{
-					Debug.Assert(null != _enumerator);
-					return _enumerator.Current;
-				}
-			}
-
-			public bool MoveNext()
-			{
-				if (null == _enumerator)
-				{
-					return false;
-				}
-
-				if(_version != _priorityQueue._version)
-				{
-					throw new InvalidOperationException("The collection has been modified");
-
-				}
-				if (!_enumerator.MoveNext())
-				{
-					_queueIndex = _priorityQueue.GetNextNonEmptyQueue(_queueIndex);
-					if(-1 == _queueIndex)
-					{
-						return false;
-					}
-					_enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator();
-					_enumerator.MoveNext();
-					return true;
-				}
-				return true;
-			}
-
-			#endregion
-		}
-
-		#endregion
-	}
-
-	#endregion
-}
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace Amib.Threading.Internal
+{
+	#region PriorityQueue class
+
+	/// <summary>
+	/// PriorityQueue class
+	/// This class is not thread safe because we use external lock
+	/// </summary>
+	public sealed class PriorityQueue : IEnumerable
+	{
+		#region Private members
+
+		/// <summary>
+		/// The number of queues, there is one for each type of priority
+		/// </summary>
+		private const int _queuesCount = WorkItemPriority.Highest-WorkItemPriority.Lowest+1;
+
+		/// <summary>
+		/// Work items queues. There is one for each type of priority
+		/// </summary>
+        private readonly LinkedList<IHasWorkItemPriority>[] _queues = new LinkedList<IHasWorkItemPriority>[_queuesCount];
+
+		/// <summary>
+		/// The total number of work items within the queues 
+		/// </summary>
+		private int _workItemsCount;
+
+		/// <summary>
+		/// Use with IEnumerable interface
+		/// </summary>
+		private int _version;
+
+		#endregion
+
+		#region Contructor
+
+		public PriorityQueue()
+		{
+			for(int i = 0; i < _queues.Length; ++i)
+			{
+                _queues[i] = new LinkedList<IHasWorkItemPriority>();
+			}
+		}
+
+		#endregion
+
+		#region Methods
+
+		/// <summary>
+		/// Enqueue a work item.
+		/// </summary>
+		/// <param name="workItem">A work item</param>
+		public void Enqueue(IHasWorkItemPriority workItem)
+		{
+			Debug.Assert(null != workItem);
+
+			int queueIndex = _queuesCount-(int)workItem.WorkItemPriority-1;
+			Debug.Assert(queueIndex >= 0);
+			Debug.Assert(queueIndex < _queuesCount);
+
+			_queues[queueIndex].AddLast(workItem);
+			++_workItemsCount;
+			++_version;
+		}
+
+		/// <summary>
+		/// Dequeque a work item.
+		/// </summary>
+		/// <returns>Returns the next work item</returns>
+		public IHasWorkItemPriority Dequeue()
+		{
+			IHasWorkItemPriority workItem = null;
+
+			if(_workItemsCount > 0)
+			{
+				int queueIndex = GetNextNonEmptyQueue(-1);
+				Debug.Assert(queueIndex >= 0);
+                workItem = _queues[queueIndex].First.Value;
+				_queues[queueIndex].RemoveFirst();
+				Debug.Assert(null != workItem);
+				--_workItemsCount;
+				++_version;
+			}
+
+			return workItem;
+		}
+
+		/// <summary>
+		/// Find the next non empty queue starting at queue queueIndex+1
+		/// </summary>
+		/// <param name="queueIndex">The index-1 to start from</param>
+		/// <returns>
+		/// The index of the next non empty queue or -1 if all the queues are empty
+		/// </returns>
+		private int GetNextNonEmptyQueue(int queueIndex)
+		{
+			for(int i = queueIndex+1; i < _queuesCount; ++i)
+			{
+				if(_queues[i].Count > 0)
+				{
+					return i;
+				}
+			}
+			return -1;
+		}
+
+		/// <summary>
+		/// The number of work items 
+		/// </summary>
+		public int Count
+		{
+			get
+			{
+				return _workItemsCount;
+			}
+		}
+
+		/// <summary>
+		/// Clear all the work items 
+		/// </summary>
+		public void Clear()
+		{
+			if (_workItemsCount > 0)
+			{
+				foreach(LinkedList<IHasWorkItemPriority> queue in _queues)
+				{
+					queue.Clear();
+				}
+				_workItemsCount = 0;
+				++_version;
+			}
+		}
+
+		#endregion
+
+		#region IEnumerable Members
+
+		/// <summary>
+		/// Returns an enumerator to iterate over the work items
+		/// </summary>
+		/// <returns>Returns an enumerator</returns>
+		public IEnumerator GetEnumerator()
+		{
+			return new PriorityQueueEnumerator(this);
+		}
+
+		#endregion
+
+		#region PriorityQueueEnumerator
+
+		/// <summary>
+		/// The class the implements the enumerator
+		/// </summary>
+		private class PriorityQueueEnumerator : IEnumerator
+		{
+			private readonly PriorityQueue _priorityQueue;
+			private int _version;
+			private int _queueIndex;
+			private IEnumerator _enumerator;
+
+			public PriorityQueueEnumerator(PriorityQueue priorityQueue)
+			{
+				_priorityQueue = priorityQueue;
+				_version = _priorityQueue._version;
+				_queueIndex = _priorityQueue.GetNextNonEmptyQueue(-1);
+				if (_queueIndex >= 0)
+				{
+					_enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator();
+				}
+				else
+				{
+					_enumerator = null;
+				}
+			}
+
+			#region IEnumerator Members
+
+			public void Reset()
+			{
+				_version = _priorityQueue._version;
+				_queueIndex = _priorityQueue.GetNextNonEmptyQueue(-1);
+				if (_queueIndex >= 0)
+				{
+					_enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator();
+				}
+				else
+				{
+					_enumerator = null;
+				}
+			}
+
+			public object Current
+			{
+				get
+				{
+					Debug.Assert(null != _enumerator);
+					return _enumerator.Current;
+				}
+			}
+
+			public bool MoveNext()
+			{
+				if (null == _enumerator)
+				{
+					return false;
+				}
+
+				if(_version != _priorityQueue._version)
+				{
+					throw new InvalidOperationException("The collection has been modified");
+
+				}
+				if (!_enumerator.MoveNext())
+				{
+					_queueIndex = _priorityQueue.GetNextNonEmptyQueue(_queueIndex);
+					if(-1 == _queueIndex)
+					{
+						return false;
+					}
+					_enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator();
+					_enumerator.MoveNext();
+					return true;
+				}
+				return true;
+			}
+
+			#endregion
+		}
+
+		#endregion
+	}
+
+	#endregion
+}

+ 23 - 23
ThirdParty/SmartThreadPool/Properties/AssemblyInfo.cs

@@ -1,23 +1,23 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-[assembly: AssemblyTitle("Amib.Threading")]
-[assembly: AssemblyDescription("Smart Thread Pool")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Amib.Threading")]
-[assembly: AssemblyCopyright("")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: ComVisible(false)]
-[assembly: Guid("c764a3de-c4f8-434d-85b5-a09830d1e44f")]
-[assembly: AssemblyVersion("2.2.3.0")]
-
-#if (_PUBLISH)
-[assembly: InternalsVisibleTo("STPTests,PublicKey=00240000048000009400000006020000002400005253413100040000010001004fe3d39add741ba7c8d52cd1eb0d94c7d79060ad956cbaff0e51c1dce94db10356b261778bc1ac3114b3218434da6fcd8416dd5507653809598f7d2afc422099ce4f6b7b0477f18e6c57c727ef2a7ab6ee56e6b4589fe44cb0e25f2875a3c65ab0383ee33c4dd93023f7ce1218bebc8b7a9a1dac878938f5c4f45ea74b6bd8ad")]
-#else
-[assembly: InternalsVisibleTo("STPTests")]
-#endif
-
-
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Amib.Threading")]
+[assembly: AssemblyDescription("Smart Thread Pool")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Amib.Threading")]
+[assembly: AssemblyCopyright("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: ComVisible(false)]
+[assembly: Guid("c764a3de-c4f8-434d-85b5-a09830d1e44f")]
+[assembly: AssemblyVersion("2.2.3.0")]
+
+#if (_PUBLISH)
+[assembly: InternalsVisibleTo("STPTests,PublicKey=00240000048000009400000006020000002400005253413100040000010001004fe3d39add741ba7c8d52cd1eb0d94c7d79060ad956cbaff0e51c1dce94db10356b261778bc1ac3114b3218434da6fcd8416dd5507653809598f7d2afc422099ce4f6b7b0477f18e6c57c727ef2a7ab6ee56e6b4589fe44cb0e25f2875a3c65ab0383ee33c4dd93023f7ce1218bebc8b7a9a1dac878938f5c4f45ea74b6bd8ad")]
+#else
+[assembly: InternalsVisibleTo("STPTests")]
+#endif
+
+

+ 16 - 16
ThirdParty/SmartThreadPool/SLExt.cs

@@ -1,16 +1,16 @@
-#if _SILVERLIGHT
-
-using System.Threading;
-
-namespace Amib.Threading
-{
-    public enum ThreadPriority
-    {
-        Lowest,
-        BelowNormal,
-        Normal,
-        AboveNormal,
-        Highest,
-    }
-}
-#endif
+#if _SILVERLIGHT
+
+using System.Threading;
+
+namespace Amib.Threading
+{
+    public enum ThreadPriority
+    {
+        Lowest,
+        BelowNormal,
+        Normal,
+        AboveNormal,
+        Highest,
+    }
+}
+#endif

+ 61 - 61
ThirdParty/SmartThreadPool/STPEventWaitHandle.cs

@@ -1,62 +1,62 @@
-#if !(_WINDOWS_CE)
-
-using System;
-using System.Threading;
-
-namespace Amib.Threading.Internal
-{
-#if _WINDOWS ||  WINDOWS_PHONE
-    internal static class STPEventWaitHandle
-    {
-        public const int WaitTimeout = Timeout.Infinite;
-
-        internal static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
-        {
-            return WaitHandle.WaitAll(waitHandles, millisecondsTimeout);
-        }
-
-        internal static int WaitAny(WaitHandle[] waitHandles)
-        {
-            return WaitHandle.WaitAny(waitHandles);
-        }
-
-        internal static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
-        {
-            return WaitHandle.WaitAny(waitHandles, millisecondsTimeout);
-        }
-
-        internal static bool WaitOne(WaitHandle waitHandle, int millisecondsTimeout, bool exitContext)
-        {
-            return waitHandle.WaitOne(millisecondsTimeout);
-        }
-    }
-#else
-    internal static class STPEventWaitHandle
-    {
-        public const int WaitTimeout = Timeout.Infinite;
-
-        internal static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
-        {
-            return WaitHandle.WaitAll(waitHandles, millisecondsTimeout, exitContext);
-        }
-
-        internal static int WaitAny(WaitHandle[] waitHandles)
-        {
-            return WaitHandle.WaitAny(waitHandles);
-        }
-
-        internal static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
-        {
-            return WaitHandle.WaitAny(waitHandles, millisecondsTimeout, exitContext);
-        }
-
-        internal static bool WaitOne(WaitHandle waitHandle, int millisecondsTimeout, bool exitContext)
-        {
-            return waitHandle.WaitOne(millisecondsTimeout, exitContext);
-        }
-    }
-#endif
-
-}
-
+#if !(_WINDOWS_CE)
+
+using System;
+using System.Threading;
+
+namespace Amib.Threading.Internal
+{
+#if _WINDOWS ||  WINDOWS_PHONE
+    internal static class STPEventWaitHandle
+    {
+        public const int WaitTimeout = Timeout.Infinite;
+
+        internal static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
+        {
+            return WaitHandle.WaitAll(waitHandles, millisecondsTimeout);
+        }
+
+        internal static int WaitAny(WaitHandle[] waitHandles)
+        {
+            return WaitHandle.WaitAny(waitHandles);
+        }
+
+        internal static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
+        {
+            return WaitHandle.WaitAny(waitHandles, millisecondsTimeout);
+        }
+
+        internal static bool WaitOne(WaitHandle waitHandle, int millisecondsTimeout, bool exitContext)
+        {
+            return waitHandle.WaitOne(millisecondsTimeout);
+        }
+    }
+#else
+    internal static class STPEventWaitHandle
+    {
+        public const int WaitTimeout = Timeout.Infinite;
+
+        internal static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
+        {
+            return WaitHandle.WaitAll(waitHandles, millisecondsTimeout, exitContext);
+        }
+
+        internal static int WaitAny(WaitHandle[] waitHandles)
+        {
+            return WaitHandle.WaitAny(waitHandles);
+        }
+
+        internal static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
+        {
+            return WaitHandle.WaitAny(waitHandles, millisecondsTimeout, exitContext);
+        }
+
+        internal static bool WaitOne(WaitHandle waitHandle, int millisecondsTimeout, bool exitContext)
+        {
+            return waitHandle.WaitOne(millisecondsTimeout, exitContext);
+        }
+    }
+#endif
+
+}
+
 #endif

+ 448 - 448
ThirdParty/SmartThreadPool/STPPerformanceCounter.cs

@@ -1,448 +1,448 @@
-using System;
-using System.Diagnostics;
-using System.Threading;
-
-namespace Amib.Threading
-{
-    public interface ISTPPerformanceCountersReader
-    {
-        long InUseThreads { get; }
-        long ActiveThreads { get; }
-        long WorkItemsQueued { get; }
-        long WorkItemsProcessed { get; }
-    }
-}
-
-namespace Amib.Threading.Internal
-{
-    internal interface ISTPInstancePerformanceCounters : IDisposable
-    {
-        void Close();
-        void SampleThreads(long activeThreads, long inUseThreads);
-        void SampleWorkItems(long workItemsQueued, long workItemsProcessed);
-        void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime);
-        void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime);
-    }
-#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
-
-    internal enum STPPerformanceCounterType
-	{
-		// Fields
-		ActiveThreads				= 0,
-		InUseThreads				= 1,
-		OverheadThreads				= 2,
-		OverheadThreadsPercent		= 3,
-		OverheadThreadsPercentBase	= 4,
-
-		WorkItems					= 5,
-		WorkItemsInQueue			= 6,
-		WorkItemsProcessed			= 7,
-
-		WorkItemsQueuedPerSecond	= 8,
-		WorkItemsProcessedPerSecond	= 9,
-
-		AvgWorkItemWaitTime			= 10,
-		AvgWorkItemWaitTimeBase		= 11,
-
-		AvgWorkItemProcessTime		= 12,
-		AvgWorkItemProcessTimeBase	= 13,
-
-		WorkItemsGroups				= 14,
-
-		LastCounter					= 14,
-	}
- 
-
-	/// <summary>
-	/// Summary description for STPPerformanceCounter.
-	/// </summary>
-	internal class STPPerformanceCounter
-	{
-		// Fields
-		private readonly PerformanceCounterType _pcType;
-		protected string _counterHelp;
-		protected string _counterName;
-
-		// Methods
-		public STPPerformanceCounter(
-			string counterName, 
-			string counterHelp, 
-			PerformanceCounterType pcType)
-		{
-			_counterName = counterName;
-			_counterHelp = counterHelp;
-			_pcType = pcType;
-		}
-
-		public void AddCounterToCollection(CounterCreationDataCollection counterData)
-		{
-			CounterCreationData counterCreationData = new CounterCreationData(
-				_counterName, 
-				_counterHelp, 
-				_pcType);
-
-			counterData.Add(counterCreationData);
-		}
- 
-		// Properties
-		public string Name
-		{
-			get
-			{
-				return _counterName;
-			}
-		}
-	}
-
-	internal class STPPerformanceCounters
-	{
-		// Fields
-		internal STPPerformanceCounter[] _stpPerformanceCounters;
-		private static readonly STPPerformanceCounters _instance;
-		internal const string _stpCategoryHelp = "SmartThreadPool performance counters";
-		internal const string _stpCategoryName = "SmartThreadPool";
-
-		// Methods
-		static STPPerformanceCounters()
-		{
-			_instance = new STPPerformanceCounters();
-		}
- 
-		private STPPerformanceCounters()
-		{
-			STPPerformanceCounter[] stpPerformanceCounters = new STPPerformanceCounter[] 
-				{ 
-					new STPPerformanceCounter("Active threads", "The current number of available in the thread pool.", PerformanceCounterType.NumberOfItems32), 
-					new STPPerformanceCounter("In use threads", "The current number of threads that execute a work item.", PerformanceCounterType.NumberOfItems32), 
-					new STPPerformanceCounter("Overhead threads", "The current number of threads that are active, but are not in use.", PerformanceCounterType.NumberOfItems32), 
-					new STPPerformanceCounter("% overhead threads", "The current number of threads that are active, but are not in use in percents.", PerformanceCounterType.RawFraction), 
-					new STPPerformanceCounter("% overhead threads base", "The current number of threads that are active, but are not in use in percents.", PerformanceCounterType.RawBase), 
-
-					new STPPerformanceCounter("Work Items", "The number of work items in the Smart Thread Pool. Both queued and processed.", PerformanceCounterType.NumberOfItems32), 
-					new STPPerformanceCounter("Work Items in queue", "The current number of work items in the queue", PerformanceCounterType.NumberOfItems32), 
-					new STPPerformanceCounter("Work Items processed", "The number of work items already processed", PerformanceCounterType.NumberOfItems32), 
-
-					new STPPerformanceCounter("Work Items queued/sec", "The number of work items queued per second", PerformanceCounterType.RateOfCountsPerSecond32), 
-					new STPPerformanceCounter("Work Items processed/sec", "The number of work items processed per second", PerformanceCounterType.RateOfCountsPerSecond32), 
-
-					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), 
-					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), 
-
-					new STPPerformanceCounter("Avg. Work Item process time/sec", "The average time it takes to process a work item.", PerformanceCounterType.AverageCount64), 
-					new STPPerformanceCounter("Avg. Work Item process time base", "The average time it takes to process a work item.", PerformanceCounterType.AverageBase), 
-
-					new STPPerformanceCounter("Work Items Groups", "The current number of work item groups associated with the Smart Thread Pool.", PerformanceCounterType.NumberOfItems32), 
-				};
-
-			_stpPerformanceCounters = stpPerformanceCounters;
-			SetupCategory();
-		}
- 
-		private void SetupCategory()
-		{
-			if (!PerformanceCounterCategory.Exists(_stpCategoryName))
-			{
-				CounterCreationDataCollection counters = new CounterCreationDataCollection();
-
-				for (int i = 0; i < _stpPerformanceCounters.Length; i++)
-				{
-					_stpPerformanceCounters[i].AddCounterToCollection(counters);
-				}
-
-				PerformanceCounterCategory.Create(
-					_stpCategoryName, 
-					_stpCategoryHelp, 
-                    PerformanceCounterCategoryType.MultiInstance,
-					counters);
-					
-			}
-		}
- 
-		// Properties
-		public static STPPerformanceCounters Instance
-		{
-			get
-			{
-				return _instance;
-			}
-		}
- 	}
-
-	internal class STPInstancePerformanceCounter : IDisposable
-	{
-		// Fields
-        private bool _isDisposed;
-		private PerformanceCounter _pcs;
-
-		// Methods
-		protected STPInstancePerformanceCounter()
-		{
-            _isDisposed = false;
-		}
-
-		public STPInstancePerformanceCounter(
-			string instance, 
-			STPPerformanceCounterType spcType) : this()
-		{
-			STPPerformanceCounters counters = STPPerformanceCounters.Instance;
-			_pcs = new PerformanceCounter(
-				STPPerformanceCounters._stpCategoryName, 
-				counters._stpPerformanceCounters[(int) spcType].Name, 
-				instance, 
-				false);
-			_pcs.RawValue = _pcs.RawValue;
-		}
-
-
-		public void Close()
-		{
-			if (_pcs != null)
-			{
-				_pcs.RemoveInstance();
-				_pcs.Close();
-				_pcs = null;
-			}
-		}
- 
-		public void Dispose()
-		{
-            Dispose(true);
-		}
-
-        public virtual void Dispose(bool disposing)
-        {
-            if (!_isDisposed)
-            {
-                if (disposing)
-                {
-                    Close();
-                }
-            }
-            _isDisposed = true;
-        }
- 
-		public virtual void Increment()
-		{
-			_pcs.Increment();
-		}
- 
-		public virtual void IncrementBy(long val)
-		{
-			_pcs.IncrementBy(val);
-		}
-
-		public virtual void Set(long val)
-		{
-			_pcs.RawValue = val;
-		}
-	}
-
-	internal class STPInstanceNullPerformanceCounter : STPInstancePerformanceCounter
-	{
-		// Methods
-		public override void Increment() {}
-		public override void IncrementBy(long value) {}
-		public override void Set(long val) {}
-	}
-
-
-
-	internal class STPInstancePerformanceCounters : ISTPInstancePerformanceCounters
-	{
-        private bool _isDisposed;
-		// Fields
-		private STPInstancePerformanceCounter[] _pcs;
-		private static readonly STPInstancePerformanceCounter _stpInstanceNullPerformanceCounter;
-
-		// Methods
-		static STPInstancePerformanceCounters()
-		{
-			_stpInstanceNullPerformanceCounter = new STPInstanceNullPerformanceCounter();
-		}
- 
-		public STPInstancePerformanceCounters(string instance)
-		{
-            _isDisposed = false;
-			_pcs = new STPInstancePerformanceCounter[(int)STPPerformanceCounterType.LastCounter];
-
-            // Call the STPPerformanceCounters.Instance so the static constructor will
-            // intialize the STPPerformanceCounters singleton.
-			STPPerformanceCounters.Instance.GetHashCode();
-
-			for (int i = 0; i < _pcs.Length; i++)
-			{
-				if (instance != null)
-				{
-					_pcs[i] = new STPInstancePerformanceCounter(
-						instance, 
-						(STPPerformanceCounterType) i);
-				}
-				else
-				{
-					_pcs[i] = _stpInstanceNullPerformanceCounter;
-				}
-			}
-		}
- 
-
-		public void Close()
-		{
-			if (null != _pcs)
-			{
-				for (int i = 0; i < _pcs.Length; i++)
-				{
-                    if (null != _pcs[i])
-                    {
-                        _pcs[i].Dispose();
-                    }
-				}
-				_pcs = null;
-			}
-		}
-
-		public void Dispose()
-		{
-            Dispose(true);
-		}
-
-        public virtual void Dispose(bool disposing)
-        {
-            if (!_isDisposed)
-            {
-                if (disposing)
-                {
-                    Close();
-                }
-            }
-            _isDisposed = true;
-        }
- 
-		private STPInstancePerformanceCounter GetCounter(STPPerformanceCounterType spcType)
-		{
-			return _pcs[(int) spcType];
-		}
-
-		public void SampleThreads(long activeThreads, long inUseThreads)
-		{
-			GetCounter(STPPerformanceCounterType.ActiveThreads).Set(activeThreads);
-			GetCounter(STPPerformanceCounterType.InUseThreads).Set(inUseThreads);
-			GetCounter(STPPerformanceCounterType.OverheadThreads).Set(activeThreads-inUseThreads);
-
-			GetCounter(STPPerformanceCounterType.OverheadThreadsPercentBase).Set(activeThreads-inUseThreads);
-			GetCounter(STPPerformanceCounterType.OverheadThreadsPercent).Set(inUseThreads);
-		}
-
-		public void SampleWorkItems(long workItemsQueued, long workItemsProcessed)
-		{
-			GetCounter(STPPerformanceCounterType.WorkItems).Set(workItemsQueued+workItemsProcessed);
-			GetCounter(STPPerformanceCounterType.WorkItemsInQueue).Set(workItemsQueued);
-			GetCounter(STPPerformanceCounterType.WorkItemsProcessed).Set(workItemsProcessed);
-
-			GetCounter(STPPerformanceCounterType.WorkItemsQueuedPerSecond).Set(workItemsQueued);
-			GetCounter(STPPerformanceCounterType.WorkItemsProcessedPerSecond).Set(workItemsProcessed);
-		}
-
-		public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime)
-		{
-			GetCounter(STPPerformanceCounterType.AvgWorkItemWaitTime).IncrementBy((long)workItemWaitTime.TotalMilliseconds);
-			GetCounter(STPPerformanceCounterType.AvgWorkItemWaitTimeBase).Increment();
-		}
-
-		public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime)
-		{
-			GetCounter(STPPerformanceCounterType.AvgWorkItemProcessTime).IncrementBy((long)workItemProcessTime.TotalMilliseconds);
-			GetCounter(STPPerformanceCounterType.AvgWorkItemProcessTimeBase).Increment();
-		}
-    }
-#endif
-
-    internal class NullSTPInstancePerformanceCounters : ISTPInstancePerformanceCounters, ISTPPerformanceCountersReader
-	{
-		private static readonly NullSTPInstancePerformanceCounters _instance = new NullSTPInstancePerformanceCounters();
-
-		public static NullSTPInstancePerformanceCounters Instance
-		{
-			get { return _instance; }
-		}
-
- 		public void Close() {}
-		public void Dispose() {}
- 
-		public void SampleThreads(long activeThreads, long inUseThreads) {}
-		public void SampleWorkItems(long workItemsQueued, long workItemsProcessed) {}
-		public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime) {}
-		public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime) {}
-        public long InUseThreads
-        {
-            get { return 0; }
-        }
-
-        public long ActiveThreads
-        {
-            get { return 0; }
-        }
-
-        public long WorkItemsQueued
-        {
-            get { return 0; }
-        }
-
-        public long WorkItemsProcessed
-        {
-            get { return 0; }
-        }
-	}
-
-    internal class LocalSTPInstancePerformanceCounters : ISTPInstancePerformanceCounters, ISTPPerformanceCountersReader
-    {
-        public void Close() { }
-        public void Dispose() { }
-
-        private long _activeThreads;
-        private long _inUseThreads;
-        private long _workItemsQueued;
-        private long _workItemsProcessed;
-
-        public long InUseThreads
-        {
-            get { return _inUseThreads; }
-        }
-
-        public long ActiveThreads
-        {
-            get { return _activeThreads; }
-        }
-
-        public long WorkItemsQueued
-        {
-            get { return _workItemsQueued; }
-        }
-
-        public long WorkItemsProcessed
-        {
-            get { return _workItemsProcessed; }
-        }
-
-        public void SampleThreads(long activeThreads, long inUseThreads)
-        {
-            _activeThreads = activeThreads;
-            _inUseThreads = inUseThreads;
-        }
-
-        public void SampleWorkItems(long workItemsQueued, long workItemsProcessed)
-        {
-            _workItemsQueued = workItemsQueued;
-            _workItemsProcessed = workItemsProcessed;
-        }
-
-        public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime)
-        {
-            // Not supported
-        }
-
-        public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime)
-        {
-            // Not supported
-        }
-    }
-}
+using System;
+using System.Diagnostics;
+using System.Threading;
+
+namespace Amib.Threading
+{
+    public interface ISTPPerformanceCountersReader
+    {
+        long InUseThreads { get; }
+        long ActiveThreads { get; }
+        long WorkItemsQueued { get; }
+        long WorkItemsProcessed { get; }
+    }
+}
+
+namespace Amib.Threading.Internal
+{
+    internal interface ISTPInstancePerformanceCounters : IDisposable
+    {
+        void Close();
+        void SampleThreads(long activeThreads, long inUseThreads);
+        void SampleWorkItems(long workItemsQueued, long workItemsProcessed);
+        void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime);
+        void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime);
+    }
+#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
+
+    internal enum STPPerformanceCounterType
+	{
+		// Fields
+		ActiveThreads				= 0,
+		InUseThreads				= 1,
+		OverheadThreads				= 2,
+		OverheadThreadsPercent		= 3,
+		OverheadThreadsPercentBase	= 4,
+
+		WorkItems					= 5,
+		WorkItemsInQueue			= 6,
+		WorkItemsProcessed			= 7,
+
+		WorkItemsQueuedPerSecond	= 8,
+		WorkItemsProcessedPerSecond	= 9,
+
+		AvgWorkItemWaitTime			= 10,
+		AvgWorkItemWaitTimeBase		= 11,
+
+		AvgWorkItemProcessTime		= 12,
+		AvgWorkItemProcessTimeBase	= 13,
+
+		WorkItemsGroups				= 14,
+
+		LastCounter					= 14,
+	}
+ 
+
+	/// <summary>
+	/// Summary description for STPPerformanceCounter.
+	/// </summary>
+	internal class STPPerformanceCounter
+	{
+		// Fields
+		private readonly PerformanceCounterType _pcType;
+		protected string _counterHelp;
+		protected string _counterName;
+
+		// Methods
+		public STPPerformanceCounter(
+			string counterName, 
+			string counterHelp, 
+			PerformanceCounterType pcType)
+		{
+			_counterName = counterName;
+			_counterHelp = counterHelp;
+			_pcType = pcType;
+		}
+
+		public void AddCounterToCollection(CounterCreationDataCollection counterData)
+		{
+			CounterCreationData counterCreationData = new CounterCreationData(
+				_counterName, 
+				_counterHelp, 
+				_pcType);
+
+			counterData.Add(counterCreationData);
+		}
+ 
+		// Properties
+		public string Name
+		{
+			get
+			{
+				return _counterName;
+			}
+		}
+	}
+
+	internal class STPPerformanceCounters
+	{
+		// Fields
+		internal STPPerformanceCounter[] _stpPerformanceCounters;
+		private static readonly STPPerformanceCounters _instance;
+		internal const string _stpCategoryHelp = "SmartThreadPool performance counters";
+		internal const string _stpCategoryName = "SmartThreadPool";
+
+		// Methods
+		static STPPerformanceCounters()
+		{
+			_instance = new STPPerformanceCounters();
+		}
+ 
+		private STPPerformanceCounters()
+		{
+			STPPerformanceCounter[] stpPerformanceCounters = new STPPerformanceCounter[] 
+				{ 
+					new STPPerformanceCounter("Active threads", "The current number of available in the thread pool.", PerformanceCounterType.NumberOfItems32), 
+					new STPPerformanceCounter("In use threads", "The current number of threads that execute a work item.", PerformanceCounterType.NumberOfItems32), 
+					new STPPerformanceCounter("Overhead threads", "The current number of threads that are active, but are not in use.", PerformanceCounterType.NumberOfItems32), 
+					new STPPerformanceCounter("% overhead threads", "The current number of threads that are active, but are not in use in percents.", PerformanceCounterType.RawFraction), 
+					new STPPerformanceCounter("% overhead threads base", "The current number of threads that are active, but are not in use in percents.", PerformanceCounterType.RawBase), 
+
+					new STPPerformanceCounter("Work Items", "The number of work items in the Smart Thread Pool. Both queued and processed.", PerformanceCounterType.NumberOfItems32), 
+					new STPPerformanceCounter("Work Items in queue", "The current number of work items in the queue", PerformanceCounterType.NumberOfItems32), 
+					new STPPerformanceCounter("Work Items processed", "The number of work items already processed", PerformanceCounterType.NumberOfItems32), 
+
+					new STPPerformanceCounter("Work Items queued/sec", "The number of work items queued per second", PerformanceCounterType.RateOfCountsPerSecond32), 
+					new STPPerformanceCounter("Work Items processed/sec", "The number of work items processed per second", PerformanceCounterType.RateOfCountsPerSecond32), 
+
+					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), 
+					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), 
+
+					new STPPerformanceCounter("Avg. Work Item process time/sec", "The average time it takes to process a work item.", PerformanceCounterType.AverageCount64), 
+					new STPPerformanceCounter("Avg. Work Item process time base", "The average time it takes to process a work item.", PerformanceCounterType.AverageBase), 
+
+					new STPPerformanceCounter("Work Items Groups", "The current number of work item groups associated with the Smart Thread Pool.", PerformanceCounterType.NumberOfItems32), 
+				};
+
+			_stpPerformanceCounters = stpPerformanceCounters;
+			SetupCategory();
+		}
+ 
+		private void SetupCategory()
+		{
+			if (!PerformanceCounterCategory.Exists(_stpCategoryName))
+			{
+				CounterCreationDataCollection counters = new CounterCreationDataCollection();
+
+				for (int i = 0; i < _stpPerformanceCounters.Length; i++)
+				{
+					_stpPerformanceCounters[i].AddCounterToCollection(counters);
+				}
+
+				PerformanceCounterCategory.Create(
+					_stpCategoryName, 
+					_stpCategoryHelp, 
+                    PerformanceCounterCategoryType.MultiInstance,
+					counters);
+					
+			}
+		}
+ 
+		// Properties
+		public static STPPerformanceCounters Instance
+		{
+			get
+			{
+				return _instance;
+			}
+		}
+ 	}
+
+	internal class STPInstancePerformanceCounter : IDisposable
+	{
+		// Fields
+        private bool _isDisposed;
+		private PerformanceCounter _pcs;
+
+		// Methods
+		protected STPInstancePerformanceCounter()
+		{
+            _isDisposed = false;
+		}
+
+		public STPInstancePerformanceCounter(
+			string instance, 
+			STPPerformanceCounterType spcType) : this()
+		{
+			STPPerformanceCounters counters = STPPerformanceCounters.Instance;
+			_pcs = new PerformanceCounter(
+				STPPerformanceCounters._stpCategoryName, 
+				counters._stpPerformanceCounters[(int) spcType].Name, 
+				instance, 
+				false);
+			_pcs.RawValue = _pcs.RawValue;
+		}
+
+
+		public void Close()
+		{
+			if (_pcs != null)
+			{
+				_pcs.RemoveInstance();
+				_pcs.Close();
+				_pcs = null;
+			}
+		}
+ 
+		public void Dispose()
+		{
+            Dispose(true);
+		}
+
+        public virtual void Dispose(bool disposing)
+        {
+            if (!_isDisposed)
+            {
+                if (disposing)
+                {
+                    Close();
+                }
+            }
+            _isDisposed = true;
+        }
+ 
+		public virtual void Increment()
+		{
+			_pcs.Increment();
+		}
+ 
+		public virtual void IncrementBy(long val)
+		{
+			_pcs.IncrementBy(val);
+		}
+
+		public virtual void Set(long val)
+		{
+			_pcs.RawValue = val;
+		}
+	}
+
+	internal class STPInstanceNullPerformanceCounter : STPInstancePerformanceCounter
+	{
+		// Methods
+		public override void Increment() {}
+		public override void IncrementBy(long value) {}
+		public override void Set(long val) {}
+	}
+
+
+
+	internal class STPInstancePerformanceCounters : ISTPInstancePerformanceCounters
+	{
+        private bool _isDisposed;
+		// Fields
+		private STPInstancePerformanceCounter[] _pcs;
+		private static readonly STPInstancePerformanceCounter _stpInstanceNullPerformanceCounter;
+
+		// Methods
+		static STPInstancePerformanceCounters()
+		{
+			_stpInstanceNullPerformanceCounter = new STPInstanceNullPerformanceCounter();
+		}
+ 
+		public STPInstancePerformanceCounters(string instance)
+		{
+            _isDisposed = false;
+			_pcs = new STPInstancePerformanceCounter[(int)STPPerformanceCounterType.LastCounter];
+
+            // Call the STPPerformanceCounters.Instance so the static constructor will
+            // intialize the STPPerformanceCounters singleton.
+			STPPerformanceCounters.Instance.GetHashCode();
+
+			for (int i = 0; i < _pcs.Length; i++)
+			{
+				if (instance != null)
+				{
+					_pcs[i] = new STPInstancePerformanceCounter(
+						instance, 
+						(STPPerformanceCounterType) i);
+				}
+				else
+				{
+					_pcs[i] = _stpInstanceNullPerformanceCounter;
+				}
+			}
+		}
+ 
+
+		public void Close()
+		{
+			if (null != _pcs)
+			{
+				for (int i = 0; i < _pcs.Length; i++)
+				{
+                    if (null != _pcs[i])
+                    {
+                        _pcs[i].Dispose();
+                    }
+				}
+				_pcs = null;
+			}
+		}
+
+		public void Dispose()
+		{
+            Dispose(true);
+		}
+
+        public virtual void Dispose(bool disposing)
+        {
+            if (!_isDisposed)
+            {
+                if (disposing)
+                {
+                    Close();
+                }
+            }
+            _isDisposed = true;
+        }
+ 
+		private STPInstancePerformanceCounter GetCounter(STPPerformanceCounterType spcType)
+		{
+			return _pcs[(int) spcType];
+		}
+
+		public void SampleThreads(long activeThreads, long inUseThreads)
+		{
+			GetCounter(STPPerformanceCounterType.ActiveThreads).Set(activeThreads);
+			GetCounter(STPPerformanceCounterType.InUseThreads).Set(inUseThreads);
+			GetCounter(STPPerformanceCounterType.OverheadThreads).Set(activeThreads-inUseThreads);
+
+			GetCounter(STPPerformanceCounterType.OverheadThreadsPercentBase).Set(activeThreads-inUseThreads);
+			GetCounter(STPPerformanceCounterType.OverheadThreadsPercent).Set(inUseThreads);
+		}
+
+		public void SampleWorkItems(long workItemsQueued, long workItemsProcessed)
+		{
+			GetCounter(STPPerformanceCounterType.WorkItems).Set(workItemsQueued+workItemsProcessed);
+			GetCounter(STPPerformanceCounterType.WorkItemsInQueue).Set(workItemsQueued);
+			GetCounter(STPPerformanceCounterType.WorkItemsProcessed).Set(workItemsProcessed);
+
+			GetCounter(STPPerformanceCounterType.WorkItemsQueuedPerSecond).Set(workItemsQueued);
+			GetCounter(STPPerformanceCounterType.WorkItemsProcessedPerSecond).Set(workItemsProcessed);
+		}
+
+		public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime)
+		{
+			GetCounter(STPPerformanceCounterType.AvgWorkItemWaitTime).IncrementBy((long)workItemWaitTime.TotalMilliseconds);
+			GetCounter(STPPerformanceCounterType.AvgWorkItemWaitTimeBase).Increment();
+		}
+
+		public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime)
+		{
+			GetCounter(STPPerformanceCounterType.AvgWorkItemProcessTime).IncrementBy((long)workItemProcessTime.TotalMilliseconds);
+			GetCounter(STPPerformanceCounterType.AvgWorkItemProcessTimeBase).Increment();
+		}
+    }
+#endif
+
+    internal class NullSTPInstancePerformanceCounters : ISTPInstancePerformanceCounters, ISTPPerformanceCountersReader
+	{
+		private static readonly NullSTPInstancePerformanceCounters _instance = new NullSTPInstancePerformanceCounters();
+
+		public static NullSTPInstancePerformanceCounters Instance
+		{
+			get { return _instance; }
+		}
+
+ 		public void Close() {}
+		public void Dispose() {}
+ 
+		public void SampleThreads(long activeThreads, long inUseThreads) {}
+		public void SampleWorkItems(long workItemsQueued, long workItemsProcessed) {}
+		public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime) {}
+		public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime) {}
+        public long InUseThreads
+        {
+            get { return 0; }
+        }
+
+        public long ActiveThreads
+        {
+            get { return 0; }
+        }
+
+        public long WorkItemsQueued
+        {
+            get { return 0; }
+        }
+
+        public long WorkItemsProcessed
+        {
+            get { return 0; }
+        }
+	}
+
+    internal class LocalSTPInstancePerformanceCounters : ISTPInstancePerformanceCounters, ISTPPerformanceCountersReader
+    {
+        public void Close() { }
+        public void Dispose() { }
+
+        private long _activeThreads;
+        private long _inUseThreads;
+        private long _workItemsQueued;
+        private long _workItemsProcessed;
+
+        public long InUseThreads
+        {
+            get { return _inUseThreads; }
+        }
+
+        public long ActiveThreads
+        {
+            get { return _activeThreads; }
+        }
+
+        public long WorkItemsQueued
+        {
+            get { return _workItemsQueued; }
+        }
+
+        public long WorkItemsProcessed
+        {
+            get { return _workItemsProcessed; }
+        }
+
+        public void SampleThreads(long activeThreads, long inUseThreads)
+        {
+            _activeThreads = activeThreads;
+            _inUseThreads = inUseThreads;
+        }
+
+        public void SampleWorkItems(long workItemsQueued, long workItemsProcessed)
+        {
+            _workItemsQueued = workItemsQueued;
+            _workItemsProcessed = workItemsProcessed;
+        }
+
+        public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime)
+        {
+            // Not supported
+        }
+
+        public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime)
+        {
+            // Not supported
+        }
+    }
+}

+ 212 - 212
ThirdParty/SmartThreadPool/STPStartInfo.cs

@@ -1,212 +1,212 @@
-using System;
-using System.Threading;
-
-namespace Amib.Threading
-{
-	/// <summary>
-	/// Summary description for STPStartInfo.
-	/// </summary>
-    public class STPStartInfo : WIGStartInfo
-    {
-        private int _idleTimeout = SmartThreadPool.DefaultIdleTimeout;
-        private int _minWorkerThreads = SmartThreadPool.DefaultMinWorkerThreads;
-        private int _maxWorkerThreads = SmartThreadPool.DefaultMaxWorkerThreads;
-#if !(WINDOWS_PHONE)
-        private ThreadPriority _threadPriority = SmartThreadPool.DefaultThreadPriority;
-#endif
-        private string _performanceCounterInstanceName = SmartThreadPool.DefaultPerformanceCounterInstanceName;
-        private bool _areThreadsBackground = SmartThreadPool.DefaultAreThreadsBackground;
-        private bool _enableLocalPerformanceCounters;
-        private string _threadPoolName = SmartThreadPool.DefaultThreadPoolName;
-        private int? _maxStackSize = SmartThreadPool.DefaultMaxStackSize;
-
-        public STPStartInfo()
-        {
-            _performanceCounterInstanceName = SmartThreadPool.DefaultPerformanceCounterInstanceName;
-#if !(WINDOWS_PHONE)
-            _threadPriority = SmartThreadPool.DefaultThreadPriority;
-#endif
-            _maxWorkerThreads = SmartThreadPool.DefaultMaxWorkerThreads;
-            _idleTimeout = SmartThreadPool.DefaultIdleTimeout;
-            _minWorkerThreads = SmartThreadPool.DefaultMinWorkerThreads;
-        }
-
-	    public STPStartInfo(STPStartInfo stpStartInfo)
-            : base(stpStartInfo)
-        {
-            _idleTimeout = stpStartInfo.IdleTimeout;
-            _minWorkerThreads = stpStartInfo.MinWorkerThreads;
-            _maxWorkerThreads = stpStartInfo.MaxWorkerThreads;
-#if !(WINDOWS_PHONE)
-            _threadPriority = stpStartInfo.ThreadPriority;
-#endif
-            _performanceCounterInstanceName = stpStartInfo.PerformanceCounterInstanceName;
-            _enableLocalPerformanceCounters = stpStartInfo._enableLocalPerformanceCounters;
-            _threadPoolName = stpStartInfo._threadPoolName;
-            _areThreadsBackground = stpStartInfo.AreThreadsBackground;
-#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
-            _apartmentState = stpStartInfo._apartmentState;
-#endif
-        }
-	  
-	    /// <summary>
-	    /// Get/Set the idle timeout in milliseconds.
-	    /// If a thread is idle (starved) longer than IdleTimeout then it may quit.
-	    /// </summary>
-	    public virtual int IdleTimeout
-	    {
-	        get { return _idleTimeout; }
-	        set 
-            {
-                ThrowIfReadOnly();
-                _idleTimeout = value; 
-            }
-	    }
-
-
-	    /// <summary>
-	    /// Get/Set the lower limit of threads in the pool.
-	    /// </summary>
-	    public virtual int MinWorkerThreads
-	    {
-	        get { return _minWorkerThreads; }
-	        set 
-            {
-                ThrowIfReadOnly();
-                _minWorkerThreads = value; 
-            }
-	    }
-
-
-	    /// <summary>
-	    /// Get/Set the upper limit of threads in the pool.
-	    /// </summary>
-	    public virtual int MaxWorkerThreads
-	    {
-	        get { return _maxWorkerThreads; }
-	        set 
-            {
-                ThrowIfReadOnly();
-                _maxWorkerThreads = value; 
-            }
-	    }
-
-#if !(WINDOWS_PHONE)
-	    /// <summary>
-	    /// Get/Set the scheduling priority of the threads in the pool.
-	    /// The Os handles the scheduling.
-	    /// </summary>
-	    public virtual ThreadPriority ThreadPriority
-	    {
-	        get { return _threadPriority; }
-	        set 
-            {
-                ThrowIfReadOnly();
-                _threadPriority = value; 
-            }
-	    }
-#endif
-        /// <summary>
-        /// Get/Set the thread pool name. Threads will get names depending on this.
-        /// </summary>
-        public virtual string ThreadPoolName {
-            get { return _threadPoolName; }
-            set
-            {
-                ThrowIfReadOnly ();
-                _threadPoolName = value;
-            }
-        }
-
-	    /// <summary>
-	    /// Get/Set the performance counter instance name of this SmartThreadPool
-	    /// The default is null which indicate not to use performance counters at all.
-	    /// </summary>
-	    public virtual string PerformanceCounterInstanceName
-	    {
-	        get { return _performanceCounterInstanceName; }
-	        set 
-            {
-                ThrowIfReadOnly();
-                _performanceCounterInstanceName = value; 
-            }
-	    }
-
-        /// <summary>
-        /// Enable/Disable the local performance counter.
-        /// This enables the user to get some performance information about the SmartThreadPool 
-        /// without using Windows performance counters. (Useful on WindowsCE, Silverlight, etc.)
-        /// The default is false.
-        /// </summary>
-        public virtual bool EnableLocalPerformanceCounters
-	    {
-	        get { return _enableLocalPerformanceCounters; }
-	        set 
-			{ 
-				ThrowIfReadOnly(); 
-				_enableLocalPerformanceCounters = value; 
-			}
-	    }
-
-        /// <summary>
-        /// Get/Set backgroundness of thread in thread pool.
-        /// </summary>
-	    public virtual bool AreThreadsBackground
- 	    {
- 	        get { return _areThreadsBackground; }
- 	        set
- 	        {
- 	            ThrowIfReadOnly ();
- 	            _areThreadsBackground = value;
- 	        }
- 	    }
-
-	    /// <summary>
-        /// Get a readonly version of this STPStartInfo.
-        /// </summary>
-        /// <returns>Returns a readonly reference to this STPStartInfo</returns>
-        public new STPStartInfo AsReadOnly()
-        {
-            return new STPStartInfo(this) { _readOnly = true };
-        }
-
-#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
-
-        private ApartmentState _apartmentState = SmartThreadPool.DefaultApartmentState;
-
-        /// <summary>
-        /// Get/Set the apartment state of threads in the thread pool
-        /// </summary>
-        public ApartmentState ApartmentState
-        {
-            get { return _apartmentState; }
-            set
-            {
-                ThrowIfReadOnly();
-                _apartmentState = value;
-            }
-        } 
-
-#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
-        
-        /// <summary>
-        /// Get/Set the max stack size of threads in the thread pool
-        /// </summary>
-        public int? MaxStackSize
-        {
-            get { return _maxStackSize; }
-            set
-            {
-                ThrowIfReadOnly();
-                if (value.HasValue && value.Value < 0)
-                {
-                    throw new ArgumentOutOfRangeException("value", "Value must be greater than 0.");
-                }
-                _maxStackSize = value;
-            }
-        }
-#endif
-
-#endif
-    }
-}
+using System;
+using System.Threading;
+
+namespace Amib.Threading
+{
+	/// <summary>
+	/// Summary description for STPStartInfo.
+	/// </summary>
+    public class STPStartInfo : WIGStartInfo
+    {
+        private int _idleTimeout = SmartThreadPool.DefaultIdleTimeout;
+        private int _minWorkerThreads = SmartThreadPool.DefaultMinWorkerThreads;
+        private int _maxWorkerThreads = SmartThreadPool.DefaultMaxWorkerThreads;
+#if !(WINDOWS_PHONE)
+        private ThreadPriority _threadPriority = SmartThreadPool.DefaultThreadPriority;
+#endif
+        private string _performanceCounterInstanceName = SmartThreadPool.DefaultPerformanceCounterInstanceName;
+        private bool _areThreadsBackground = SmartThreadPool.DefaultAreThreadsBackground;
+        private bool _enableLocalPerformanceCounters;
+        private string _threadPoolName = SmartThreadPool.DefaultThreadPoolName;
+        private int? _maxStackSize = SmartThreadPool.DefaultMaxStackSize;
+
+        public STPStartInfo()
+        {
+            _performanceCounterInstanceName = SmartThreadPool.DefaultPerformanceCounterInstanceName;
+#if !(WINDOWS_PHONE)
+            _threadPriority = SmartThreadPool.DefaultThreadPriority;
+#endif
+            _maxWorkerThreads = SmartThreadPool.DefaultMaxWorkerThreads;
+            _idleTimeout = SmartThreadPool.DefaultIdleTimeout;
+            _minWorkerThreads = SmartThreadPool.DefaultMinWorkerThreads;
+        }
+
+	    public STPStartInfo(STPStartInfo stpStartInfo)
+            : base(stpStartInfo)
+        {
+            _idleTimeout = stpStartInfo.IdleTimeout;
+            _minWorkerThreads = stpStartInfo.MinWorkerThreads;
+            _maxWorkerThreads = stpStartInfo.MaxWorkerThreads;
+#if !(WINDOWS_PHONE)
+            _threadPriority = stpStartInfo.ThreadPriority;
+#endif
+            _performanceCounterInstanceName = stpStartInfo.PerformanceCounterInstanceName;
+            _enableLocalPerformanceCounters = stpStartInfo._enableLocalPerformanceCounters;
+            _threadPoolName = stpStartInfo._threadPoolName;
+            _areThreadsBackground = stpStartInfo.AreThreadsBackground;
+#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
+            _apartmentState = stpStartInfo._apartmentState;
+#endif
+        }
+	  
+	    /// <summary>
+	    /// Get/Set the idle timeout in milliseconds.
+	    /// If a thread is idle (starved) longer than IdleTimeout then it may quit.
+	    /// </summary>
+	    public virtual int IdleTimeout
+	    {
+	        get { return _idleTimeout; }
+	        set 
+            {
+                ThrowIfReadOnly();
+                _idleTimeout = value; 
+            }
+	    }
+
+
+	    /// <summary>
+	    /// Get/Set the lower limit of threads in the pool.
+	    /// </summary>
+	    public virtual int MinWorkerThreads
+	    {
+	        get { return _minWorkerThreads; }
+	        set 
+            {
+                ThrowIfReadOnly();
+                _minWorkerThreads = value; 
+            }
+	    }
+
+
+	    /// <summary>
+	    /// Get/Set the upper limit of threads in the pool.
+	    /// </summary>
+	    public virtual int MaxWorkerThreads
+	    {
+	        get { return _maxWorkerThreads; }
+	        set 
+            {
+                ThrowIfReadOnly();
+                _maxWorkerThreads = value; 
+            }
+	    }
+
+#if !(WINDOWS_PHONE)
+	    /// <summary>
+	    /// Get/Set the scheduling priority of the threads in the pool.
+	    /// The Os handles the scheduling.
+	    /// </summary>
+	    public virtual ThreadPriority ThreadPriority
+	    {
+	        get { return _threadPriority; }
+	        set 
+            {
+                ThrowIfReadOnly();
+                _threadPriority = value; 
+            }
+	    }
+#endif
+        /// <summary>
+        /// Get/Set the thread pool name. Threads will get names depending on this.
+        /// </summary>
+        public virtual string ThreadPoolName {
+            get { return _threadPoolName; }
+            set
+            {
+                ThrowIfReadOnly ();
+                _threadPoolName = value;
+            }
+        }
+
+	    /// <summary>
+	    /// Get/Set the performance counter instance name of this SmartThreadPool
+	    /// The default is null which indicate not to use performance counters at all.
+	    /// </summary>
+	    public virtual string PerformanceCounterInstanceName
+	    {
+	        get { return _performanceCounterInstanceName; }
+	        set 
+            {
+                ThrowIfReadOnly();
+                _performanceCounterInstanceName = value; 
+            }
+	    }
+
+        /// <summary>
+        /// Enable/Disable the local performance counter.
+        /// This enables the user to get some performance information about the SmartThreadPool 
+        /// without using Windows performance counters. (Useful on WindowsCE, Silverlight, etc.)
+        /// The default is false.
+        /// </summary>
+        public virtual bool EnableLocalPerformanceCounters
+	    {
+	        get { return _enableLocalPerformanceCounters; }
+	        set 
+			{ 
+				ThrowIfReadOnly(); 
+				_enableLocalPerformanceCounters = value; 
+			}
+	    }
+
+        /// <summary>
+        /// Get/Set backgroundness of thread in thread pool.
+        /// </summary>
+	    public virtual bool AreThreadsBackground
+ 	    {
+ 	        get { return _areThreadsBackground; }
+ 	        set
+ 	        {
+ 	            ThrowIfReadOnly ();
+ 	            _areThreadsBackground = value;
+ 	        }
+ 	    }
+
+	    /// <summary>
+        /// Get a readonly version of this STPStartInfo.
+        /// </summary>
+        /// <returns>Returns a readonly reference to this STPStartInfo</returns>
+        public new STPStartInfo AsReadOnly()
+        {
+            return new STPStartInfo(this) { _readOnly = true };
+        }
+
+#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
+
+        private ApartmentState _apartmentState = SmartThreadPool.DefaultApartmentState;
+
+        /// <summary>
+        /// Get/Set the apartment state of threads in the thread pool
+        /// </summary>
+        public ApartmentState ApartmentState
+        {
+            get { return _apartmentState; }
+            set
+            {
+                ThrowIfReadOnly();
+                _apartmentState = value;
+            }
+        } 
+
+#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
+        
+        /// <summary>
+        /// Get/Set the max stack size of threads in the thread pool
+        /// </summary>
+        public int? MaxStackSize
+        {
+            get { return _maxStackSize; }
+            set
+            {
+                ThrowIfReadOnly();
+                if (value.HasValue && value.Value < 0)
+                {
+                    throw new ArgumentOutOfRangeException("value", "Value must be greater than 0.");
+                }
+                _maxStackSize = value;
+            }
+        }
+#endif
+
+#endif
+    }
+}

+ 59 - 59
ThirdParty/SmartThreadPool/SmartThreadPool.ThreadEntry.cs

@@ -1,60 +1,60 @@
-
-using System;
-using Amib.Threading.Internal;
-
-namespace Amib.Threading
-{
-    public partial class SmartThreadPool
-    {
-        #region ThreadEntry class
-
-        internal class ThreadEntry
-        {
-            /// <summary>
-            /// The thread creation time
-            /// The value is stored as UTC value.
-            /// </summary>
-            private readonly DateTime _creationTime;
-
-            /// <summary>
-            /// The last time this thread has been running
-            /// It is updated by IAmAlive() method
-            /// The value is stored as UTC value.
-            /// </summary>
-            private DateTime _lastAliveTime;
-
-            /// <summary>
-            /// A reference from each thread in the thread pool to its SmartThreadPool
-            /// object container.
-            /// With this variable a thread can know whatever it belongs to a 
-            /// SmartThreadPool.
-            /// </summary>
-            private readonly SmartThreadPool _associatedSmartThreadPool;
-
-            /// <summary>
-            /// A reference to the current work item a thread from the thread pool 
-            /// is executing.
-            /// </summary>            
-            public WorkItem CurrentWorkItem { get; set; }
-
-            public ThreadEntry(SmartThreadPool stp)
-            {
-                _associatedSmartThreadPool = stp;
-                _creationTime = DateTime.UtcNow;
-                _lastAliveTime = DateTime.MinValue;
-            }
-
-            public SmartThreadPool AssociatedSmartThreadPool
-            {
-                get { return _associatedSmartThreadPool; }
-            }
-
-            public void IAmAlive()
-            {
-                _lastAliveTime = DateTime.UtcNow;
-            }
-        }
-
-        #endregion
-    }
+
+using System;
+using Amib.Threading.Internal;
+
+namespace Amib.Threading
+{
+    public partial class SmartThreadPool
+    {
+        #region ThreadEntry class
+
+        internal class ThreadEntry
+        {
+            /// <summary>
+            /// The thread creation time
+            /// The value is stored as UTC value.
+            /// </summary>
+            private readonly DateTime _creationTime;
+
+            /// <summary>
+            /// The last time this thread has been running
+            /// It is updated by IAmAlive() method
+            /// The value is stored as UTC value.
+            /// </summary>
+            private DateTime _lastAliveTime;
+
+            /// <summary>
+            /// A reference from each thread in the thread pool to its SmartThreadPool
+            /// object container.
+            /// With this variable a thread can know whatever it belongs to a 
+            /// SmartThreadPool.
+            /// </summary>
+            private readonly SmartThreadPool _associatedSmartThreadPool;
+
+            /// <summary>
+            /// A reference to the current work item a thread from the thread pool 
+            /// is executing.
+            /// </summary>            
+            public WorkItem CurrentWorkItem { get; set; }
+
+            public ThreadEntry(SmartThreadPool stp)
+            {
+                _associatedSmartThreadPool = stp;
+                _creationTime = DateTime.UtcNow;
+                _lastAliveTime = DateTime.MinValue;
+            }
+
+            public SmartThreadPool AssociatedSmartThreadPool
+            {
+                get { return _associatedSmartThreadPool; }
+            }
+
+            public void IAmAlive()
+            {
+                _lastAliveTime = DateTime.UtcNow;
+            }
+        }
+
+        #endregion
+    }
 }

+ 1732 - 1732
ThirdParty/SmartThreadPool/SmartThreadPool.cs

@@ -1,1732 +1,1732 @@
-#region Release History
-
-// Smart Thread Pool
-// 7 Aug 2004 - Initial release
-//
-// 14 Sep 2004 - Bug fixes 
-//
-// 15 Oct 2004 - Added new features
-//		- Work items return result.
-//		- Support waiting synchronization for multiple work items.
-//		- Work items can be cancelled.
-//		- Passage of the caller thread’s context to the thread in the pool.
-//		- Minimal usage of WIN32 handles.
-//		- Minor bug fixes.
-//
-// 26 Dec 2004 - Changes:
-//		- Removed static constructors.
-//      - Added finalizers.
-//		- Changed Exceptions so they are serializable.
-//		- Fixed the bug in one of the SmartThreadPool constructors.
-//		- Changed the SmartThreadPool.WaitAll() so it will support any number of waiters. 
-//        The SmartThreadPool.WaitAny() is still limited by the .NET Framework.
-//		- Added PostExecute with options on which cases to call it.
-//      - Added option to dispose of the state objects.
-//      - Added a WaitForIdle() method that waits until the work items queue is empty.
-//      - Added an STPStartInfo class for the initialization of the thread pool.
-//      - Changed exception handling so if a work item throws an exception it 
-//        is rethrown at GetResult(), rather then firing an UnhandledException event.
-//        Note that PostExecute exception are always ignored.
-//
-// 25 Mar 2005 - Changes:
-//		- Fixed lost of work items bug
-//
-// 3 Jul 2005: Changes.
-//      - Fixed bug where Enqueue() throws an exception because PopWaiter() returned null, hardly reconstructed. 
-//
-// 16 Aug 2005: Changes.
-//		- Fixed bug where the InUseThreads becomes negative when canceling work items. 
-//
-// 31 Jan 2006 - Changes:
-//		- Added work items priority
-//		- Removed support of chained delegates in callbacks and post executes (nobody really use this)
-//		- Added work items groups
-//		- Added work items groups idle event
-//		- Changed SmartThreadPool.WaitAll() behavior so when it gets empty array
-//		  it returns true rather then throwing an exception.
-//		- Added option to start the STP and the WIG as suspended
-//		- Exception behavior changed, the real exception is returned by an 
-//		  inner exception
-//		- Added option to keep the Http context of the caller thread. (Thanks to Steven T.)
-//		- Added performance counters
-//		- Added priority to the threads in the pool
-//
-// 13 Feb 2006 - Changes:
-//		- Added a call to the dispose of the Performance Counter so
-//		  their won't be a Performance Counter leak.
-//		- Added exception catch in case the Performance Counters cannot 
-//		  be created.
-//
-// 17 May 2008 - Changes:
-//      - Changed the dispose behavior and removed the Finalizers.
-//      - Enabled the change of the MaxThreads and MinThreads at run time.
-//      - Enabled the change of the Concurrency of a IWorkItemsGroup at run 
-//        time If the IWorkItemsGroup is a SmartThreadPool then the Concurrency 
-//        refers to the MaxThreads. 
-//      - Improved the cancel behavior.
-//      - Added events for thread creation and termination. 
-//      - Fixed the HttpContext context capture.
-//      - Changed internal collections so they use generic collections
-//      - Added IsIdle flag to the SmartThreadPool and IWorkItemsGroup
-//      - Added support for WinCE
-//      - Added support for Action<T> and Func<T>
-//
-// 07 April 2009 - Changes:
-//      - Added support for Silverlight and Mono
-//      - Added Join, Choice, and Pipe to SmartThreadPool.
-//      - Added local performance counters (for Mono, Silverlight, and WindowsCE)
-//      - Changed duration measures from DateTime.Now to Stopwatch.
-//      - Queues changed from System.Collections.Queue to System.Collections.Generic.LinkedList<T>.
-//
-// 21 December 2009 - Changes:
-//      - Added work item timeout (passive)
-//
-// 20 August 2012 - Changes:
-//      - Added set name to threads
-//      - Fixed the WorkItemsQueue.Dequeue. 
-//        Replaced while (!Monitor.TryEnter(this)); with lock(this) { ... }
-//      - Fixed SmartThreadPool.Pipe
-//      - Added IsBackground option to threads
-//      - Added ApartmentState to threads
-//      - Fixed thread creation when queuing many work items at the same time.
-//
-// 24 August 2012 - Changes:
-//      - Enabled cancel abort after cancel. See: http://smartthreadpool.codeplex.com/discussions/345937 by alecswan
-//      - Added option to set MaxStackSize of threads 
-
-#endregion
-
-using System;
-using System.Security;
-using System.Threading;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-
-using Amib.Threading.Internal;
-
-namespace Amib.Threading
-{
-	#region SmartThreadPool class
-	/// <summary>
-	/// Smart thread pool class.
-	/// </summary>
-	public partial class SmartThreadPool : WorkItemsGroupBase, IDisposable
-	{
-		#region Public Default Constants
-
-		/// <summary>
-		/// Default minimum number of threads the thread pool contains. (0)
-		/// </summary>
-		public const int DefaultMinWorkerThreads = 0;
-
-		/// <summary>
-		/// Default maximum number of threads the thread pool contains. (25)
-		/// </summary>
-		public const int DefaultMaxWorkerThreads = 25;
-
-		/// <summary>
-		/// Default idle timeout in milliseconds. (One minute)
-		/// </summary>
-		public const int DefaultIdleTimeout = 60*1000; // One minute
-
-		/// <summary>
-		/// Indicate to copy the security context of the caller and then use it in the call. (false)
-		/// </summary>
-		public const bool DefaultUseCallerCallContext = false; 
-
-		/// <summary>
-		/// Indicate to copy the HTTP context of the caller and then use it in the call. (false)
-		/// </summary>
-		public const bool DefaultUseCallerHttpContext = false;
-
-		/// <summary>
-		/// Indicate to dispose of the state objects if they support the IDispose interface. (false)
-		/// </summary>
-		public const bool DefaultDisposeOfStateObjects = false; 
-
-		/// <summary>
-        /// The default option to run the post execute (CallToPostExecute.Always)
-		/// </summary>
-		public const CallToPostExecute DefaultCallToPostExecute = CallToPostExecute.Always;
-
-		/// <summary>
-		/// The default post execute method to run. (None)
-		/// When null it means not to call it.
-		/// </summary>
-		public static readonly PostExecuteWorkItemCallback DefaultPostExecuteWorkItemCallback;
-
-		/// <summary>
-        /// The default work item priority (WorkItemPriority.Normal)
-		/// </summary>
-		public const WorkItemPriority DefaultWorkItemPriority = WorkItemPriority.Normal;
-
-		/// <summary>
-		/// The default is to work on work items as soon as they arrive
-		/// and not to wait for the start. (false)
-		/// </summary>
-		public const bool DefaultStartSuspended = false;
-
-		/// <summary>
-        /// The default name to use for the performance counters instance. (null)
-		/// </summary>
-		public static readonly string DefaultPerformanceCounterInstanceName;
-
-#if !(WINDOWS_PHONE)
-
-		/// <summary>
-        /// The default thread priority (ThreadPriority.Normal)
-		/// </summary>
-		public const ThreadPriority DefaultThreadPriority = ThreadPriority.Normal;
-#endif
-        /// <summary>
-        /// The default thread pool name. (SmartThreadPool)
-        /// </summary>
-        public const string DefaultThreadPoolName = "SmartThreadPool";
-
-        /// <summary>
-        /// The default Max Stack Size. (SmartThreadPool)
-        /// </summary>
-        public static readonly int? DefaultMaxStackSize = null;
-
-        /// <summary>
-        /// The default fill state with params. (false)
-        /// It is relevant only to QueueWorkItem of Action&lt;...&gt;/Func&lt;...&gt;
-        /// </summary>
-        public const bool DefaultFillStateWithArgs = false;
-
-        /// <summary>
-        /// The default thread backgroundness. (true)
-        /// </summary>
-        public const bool DefaultAreThreadsBackground = true;
-
-#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
-        /// <summary>
-        /// The default apartment state of a thread in the thread pool. 
-        /// The default is ApartmentState.Unknown which means the STP will not 
-        /// set the apartment of the thread. It will use the .NET default.
-        /// </summary>
-        public const ApartmentState DefaultApartmentState = ApartmentState.Unknown;
-#endif
-
-		#endregion
-
-        #region Member Variables
-
-		/// <summary>
-		/// Dictionary of all the threads in the thread pool.
-		/// </summary>
-        private readonly SynchronizedDictionary<Thread, ThreadEntry> _workerThreads = new SynchronizedDictionary<Thread, ThreadEntry>();
-
-		/// <summary>
-		/// Queue of work items.
-		/// </summary>
-		private readonly WorkItemsQueue _workItemsQueue = new WorkItemsQueue();
-
-		/// <summary>
-		/// Count the work items handled.
-		/// Used by the performance counter.
-		/// </summary>
-		private int _workItemsProcessed;
-
-		/// <summary>
-		/// Number of threads that currently work (not idle).
-		/// </summary>
-		private int _inUseWorkerThreads;
-
-        /// <summary>
-        /// Stores a copy of the original STPStartInfo.
-        /// It is used to change the MinThread and MaxThreads
-        /// </summary>
-        private STPStartInfo _stpStartInfo;
-
-		/// <summary>
-		/// Total number of work items that are stored in the work items queue 
-		/// plus the work items that the threads in the pool are working on.
-		/// </summary>
-		private int _currentWorkItemsCount;
-
-		/// <summary>
-		/// Signaled when the thread pool is idle, i.e. no thread is busy
-		/// and the work items queue is empty
-		/// </summary>
-		//private ManualResetEvent _isIdleWaitHandle = new ManualResetEvent(true);
-		private ManualResetEvent _isIdleWaitHandle = EventWaitHandleFactory.CreateManualResetEvent(true);
-
-		/// <summary>
-		/// An event to signal all the threads to quit immediately.
-		/// </summary>
-		//private ManualResetEvent _shuttingDownEvent = new ManualResetEvent(false);
-		private ManualResetEvent _shuttingDownEvent = EventWaitHandleFactory.CreateManualResetEvent(false);
-
-        /// <summary>
-        /// A flag to indicate if the Smart Thread Pool is now suspended.
-        /// </summary>
-        private bool _isSuspended;
-
-		/// <summary>
-		/// A flag to indicate the threads to quit.
-		/// </summary>
-		private bool _shutdown;
-
-		/// <summary>
-		/// Counts the threads created in the pool.
-		/// It is used to name the threads.
-		/// </summary>
-		private int _threadCounter;
-
-		/// <summary>
-		/// Indicate that the SmartThreadPool has been disposed
-		/// </summary>
-		private bool _isDisposed;
-
-		/// <summary>
-		/// Holds all the WorkItemsGroup instaces that have at least one 
-		/// work item int the SmartThreadPool
-		/// This variable is used in case of Shutdown
-		/// </summary>
-        private readonly SynchronizedDictionary<IWorkItemsGroup, IWorkItemsGroup> _workItemsGroups = new SynchronizedDictionary<IWorkItemsGroup, IWorkItemsGroup>();
-
-        /// <summary>
-        /// A common object for all the work items int the STP
-        /// so we can mark them to cancel in O(1)
-        /// </summary>
-        private CanceledWorkItemsGroup _canceledSmartThreadPool = new CanceledWorkItemsGroup();
-
-        /// <summary>
-        /// Windows STP performance counters
-        /// </summary>
-        private ISTPInstancePerformanceCounters _windowsPCs = NullSTPInstancePerformanceCounters.Instance;
-
-        /// <summary>
-        /// Local STP performance counters
-        /// </summary>
-        private ISTPInstancePerformanceCounters _localPCs = NullSTPInstancePerformanceCounters.Instance;
-
-
-#if (WINDOWS_PHONE) 
-        private static readonly Dictionary<int, ThreadEntry> _threadEntries = new Dictionary<int, ThreadEntry>();
-#elif (_WINDOWS_CE)
-        private static LocalDataStoreSlot _threadEntrySlot = Thread.AllocateDataSlot();
-#else
-        [ThreadStatic]
-        private static ThreadEntry _threadEntry;
-
-#endif
-
-        /// <summary>
-        /// An event to call after a thread is created, but before 
-        /// it's first use.
-        /// </summary>
-        private event ThreadInitializationHandler _onThreadInitialization;
-
-        /// <summary>
-        /// An event to call when a thread is about to exit, after 
-        /// it is no longer belong to the pool.
-        /// </summary>
-        private event ThreadTerminationHandler _onThreadTermination;
-
-        #endregion
-
-        #region Per thread properties
-
-        /// <summary>
-        /// A reference to the current work item a thread from the thread pool 
-        /// is executing.
-        /// </summary>
-        internal static ThreadEntry CurrentThreadEntry
-        {
-#if (WINDOWS_PHONE)
-            get
-            {
-                lock(_threadEntries)
-                {
-                    ThreadEntry threadEntry;
-                    if (_threadEntries.TryGetValue(Thread.CurrentThread.ManagedThreadId, out threadEntry))
-                    {
-                        return threadEntry;
-                    }
-                }
-                return null;
-            }
-            set
-            {
-                lock(_threadEntries)
-                {
-                    _threadEntries[Thread.CurrentThread.ManagedThreadId] = value;
-                }
-            }
-#elif (_WINDOWS_CE)
-            get
-            {
-                //Thread.CurrentThread.ManagedThreadId
-                return Thread.GetData(_threadEntrySlot) as ThreadEntry;
-            }
-            set
-            {
-                Thread.SetData(_threadEntrySlot, value);
-            }
-#else
-            get
-            {
-                return _threadEntry;
-            }
-            set
-            {
-                _threadEntry = value;
-            }
-#endif
-        }
-        #endregion
-
-        #region Construction and Finalization
-
-        /// <summary>
-		/// Constructor
-		/// </summary>
-		public SmartThreadPool()
-		{
-            _stpStartInfo = new STPStartInfo();
-            Initialize();
-		}
-
-		/// <summary>
-		/// Constructor
-		/// </summary>
-		/// <param name="idleTimeout">Idle timeout in milliseconds</param>
-		public SmartThreadPool(int idleTimeout)
-		{
-            _stpStartInfo = new STPStartInfo
-            {
-                IdleTimeout = idleTimeout,
-            };
-			Initialize();
-		}
-
-		/// <summary>
-		/// Constructor
-		/// </summary>
-		/// <param name="idleTimeout">Idle timeout in milliseconds</param>
-		/// <param name="maxWorkerThreads">Upper limit of threads in the pool</param>
-		public SmartThreadPool(
-			int idleTimeout,
-			int maxWorkerThreads)
-		{
-            _stpStartInfo = new STPStartInfo
-            {
-                IdleTimeout = idleTimeout,
-                MaxWorkerThreads = maxWorkerThreads,
-            };
-			Initialize();
-		}
-
-		/// <summary>
-		/// Constructor
-		/// </summary>
-		/// <param name="idleTimeout">Idle timeout in milliseconds</param>
-		/// <param name="maxWorkerThreads">Upper limit of threads in the pool</param>
-		/// <param name="minWorkerThreads">Lower limit of threads in the pool</param>
-		public SmartThreadPool(
-			int idleTimeout,
-			int maxWorkerThreads,
-			int minWorkerThreads)
-		{
-            _stpStartInfo = new STPStartInfo
-            {
-                IdleTimeout = idleTimeout,
-                MaxWorkerThreads = maxWorkerThreads,
-                MinWorkerThreads = minWorkerThreads,
-            };
-			Initialize();
-		}
-
-        /// <summary>
-        /// Constructor
-        /// </summary>
-        /// <param name="stpStartInfo">A SmartThreadPool configuration that overrides the default behavior</param>
-		public SmartThreadPool(STPStartInfo stpStartInfo)
-		{
-			_stpStartInfo = new STPStartInfo(stpStartInfo);
-			Initialize();
-		}
-
-		private void Initialize()
-		{
-            Name = _stpStartInfo.ThreadPoolName;
-			ValidateSTPStartInfo();
-
-            // _stpStartInfoRW stores a read/write copy of the STPStartInfo.
-            // Actually only MaxWorkerThreads and MinWorkerThreads are overwritten
-
-            _isSuspended = _stpStartInfo.StartSuspended;
-
-#if (_WINDOWS_CE) || (_SILVERLIGHT) || (_MONO) || (WINDOWS_PHONE)
-			if (null != _stpStartInfo.PerformanceCounterInstanceName)
-			{
-                throw new NotSupportedException("Performance counters are not implemented for Compact Framework/Silverlight/Mono, instead use StpStartInfo.EnableLocalPerformanceCounters");
-            }
-#else
-            if (null != _stpStartInfo.PerformanceCounterInstanceName)
-            {
-                try
-                {
-                    _windowsPCs = new STPInstancePerformanceCounters(_stpStartInfo.PerformanceCounterInstanceName);
-                }
-                catch (Exception e)
-                {
-                    Debug.WriteLine("Unable to create Performance Counters: " + e);
-                    _windowsPCs = NullSTPInstancePerformanceCounters.Instance;
-                }
-            }
-#endif
-
-            if (_stpStartInfo.EnableLocalPerformanceCounters)
-            {
-                _localPCs = new LocalSTPInstancePerformanceCounters();
-            }
-
-		    // If the STP is not started suspended then start the threads.
-            if (!_isSuspended)
-            {
-                StartOptimalNumberOfThreads();
-            }
-		}
-
-		private void StartOptimalNumberOfThreads()
-		{
-			int threadsCount = Math.Max(_workItemsQueue.Count, _stpStartInfo.MinWorkerThreads);
-            threadsCount = Math.Min(threadsCount, _stpStartInfo.MaxWorkerThreads);
-            threadsCount -= _workerThreads.Count;
-            if (threadsCount > 0)
-            {
-                StartThreads(threadsCount);
-            }
-		}
-
-		private void ValidateSTPStartInfo()
-		{
-            if (_stpStartInfo.MinWorkerThreads < 0)
-			{
-				throw new ArgumentOutOfRangeException(
-					"MinWorkerThreads", "MinWorkerThreads cannot be negative");
-			}
-
-            if (_stpStartInfo.MaxWorkerThreads <= 0)
-			{
-				throw new ArgumentOutOfRangeException(
-					"MaxWorkerThreads", "MaxWorkerThreads must be greater than zero");
-			}
-
-            if (_stpStartInfo.MinWorkerThreads > _stpStartInfo.MaxWorkerThreads)
-			{
-				throw new ArgumentOutOfRangeException(
-					"MinWorkerThreads, maxWorkerThreads", 
-					"MaxWorkerThreads must be greater or equal to MinWorkerThreads");
-			}
-		}
-
-		private static void ValidateCallback(Delegate callback)
-		{
-			if(callback.GetInvocationList().Length > 1)
-			{
-				throw new NotSupportedException("SmartThreadPool doesn't support delegates chains");
-			}
-		}
-
-		#endregion
-
-		#region Thread Processing
-
-		/// <summary>
-		/// Waits on the queue for a work item, shutdown, or timeout.
-		/// </summary>
-		/// <returns>
-		/// Returns the WaitingCallback or null in case of timeout or shutdown.
-		/// </returns>
-		private WorkItem Dequeue()
-		{
-			WorkItem workItem =
-                _workItemsQueue.DequeueWorkItem(_stpStartInfo.IdleTimeout, _shuttingDownEvent);
-
-			return workItem;
-		}
-
-		/// <summary>
-		/// Put a new work item in the queue
-		/// </summary>
-		/// <param name="workItem">A work item to queue</param>
-		internal override void Enqueue(WorkItem workItem)
-		{
-			// Make sure the workItem is not null
-			Debug.Assert(null != workItem);
-
-			IncrementWorkItemsCount();
-
-            workItem.CanceledSmartThreadPool = _canceledSmartThreadPool;
-			_workItemsQueue.EnqueueWorkItem(workItem);
-			workItem.WorkItemIsQueued();
-
-			// If all the threads are busy then try to create a new one
-			if (_currentWorkItemsCount > _workerThreads.Count) 
-			{
-				StartThreads(1);
-			}
-		}
-
-		private void IncrementWorkItemsCount()
-		{
-			_windowsPCs.SampleWorkItems(_workItemsQueue.Count, _workItemsProcessed);
-            _localPCs.SampleWorkItems(_workItemsQueue.Count, _workItemsProcessed);
-
-			int count = Interlocked.Increment(ref _currentWorkItemsCount);
-			//Trace.WriteLine("WorkItemsCount = " + _currentWorkItemsCount.ToString());
-			if (count == 1) 
-			{
-                IsIdle = false;
-                _isIdleWaitHandle.Reset();
-			}
-		}
-
-		private void DecrementWorkItemsCount()
-		{
-            int count = Interlocked.Decrement(ref _currentWorkItemsCount);
-            //Trace.WriteLine("WorkItemsCount = " + _currentWorkItemsCount.ToString());
-            if (count == 0)
-            {
-                IsIdle = true;
-                _isIdleWaitHandle.Set();
-            }
-
-            Interlocked.Increment(ref _workItemsProcessed);
-
-            if (!_shutdown)
-            {
-			    // The counter counts even if the work item was cancelled
-			    _windowsPCs.SampleWorkItems(_workItemsQueue.Count, _workItemsProcessed);
-                _localPCs.SampleWorkItems(_workItemsQueue.Count, _workItemsProcessed);
-            }
-
-		}
-
-		internal void RegisterWorkItemsGroup(IWorkItemsGroup workItemsGroup)
-		{
-			_workItemsGroups[workItemsGroup] = workItemsGroup;
-		}
-
-		internal void UnregisterWorkItemsGroup(IWorkItemsGroup workItemsGroup)
-		{
-			if (_workItemsGroups.Contains(workItemsGroup))
-			{
-				_workItemsGroups.Remove(workItemsGroup);
-			}
-		}
-
-		/// <summary>
-		/// Inform that the current thread is about to quit or quiting.
-		/// The same thread may call this method more than once.
-		/// </summary>
-		private void InformCompleted()
-		{
-			// There is no need to lock the two methods together 
-			// since only the current thread removes itself
-			// and the _workerThreads is a synchronized dictionary
-			if (_workerThreads.Contains(Thread.CurrentThread))
-			{
-				_workerThreads.Remove(Thread.CurrentThread);
-				_windowsPCs.SampleThreads(_workerThreads.Count, _inUseWorkerThreads);
-                _localPCs.SampleThreads(_workerThreads.Count, _inUseWorkerThreads);
-			}
-		}
-
-		/// <summary>
-		/// Starts new threads
-		/// </summary>
-		/// <param name="threadsCount">The number of threads to start</param>
-		private void StartThreads(int threadsCount)
-		{
-            if (_isSuspended)
-			{
-				return;
-			}
-
-			lock(_workerThreads.SyncRoot)
-			{
-				// Don't start threads on shut down
-				if (_shutdown)
-				{
-					return;
-				}
-
-				for(int i = 0; i < threadsCount; ++i)
-				{
-					// Don't create more threads then the upper limit
-                    if (_workerThreads.Count >= _stpStartInfo.MaxWorkerThreads)
-					{
-						return;
-					}
-
-                    // Create a new thread
-
-#if (_SILVERLIGHT) || (WINDOWS_PHONE)
-					Thread workerThread = new Thread(ProcessQueuedItems);
-#else
-                    Thread workerThread =
-                        _stpStartInfo.MaxStackSize.HasValue
-                        ? new Thread(ProcessQueuedItems, _stpStartInfo.MaxStackSize.Value)
-                        : new Thread(ProcessQueuedItems);
-#endif
-					// Configure the new thread and start it
-					workerThread.Name = "STP " + Name + " Thread #" + _threadCounter;
-                    workerThread.IsBackground = _stpStartInfo.AreThreadsBackground;
-
-#if !(_SILVERLIGHT) && !(_WINDOWS_CE) && !(WINDOWS_PHONE)
-                    if (_stpStartInfo.ApartmentState != ApartmentState.Unknown)
-                    {
-                        workerThread.SetApartmentState(_stpStartInfo.ApartmentState);
-                    }
-#endif
-
-#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
-                    workerThread.Priority = _stpStartInfo.ThreadPriority;
-#endif
-                    workerThread.Start();
-					++_threadCounter;
-
-                    // Add it to the dictionary and update its creation time.
-                    _workerThreads[workerThread] = new ThreadEntry(this);
-
-					_windowsPCs.SampleThreads(_workerThreads.Count, _inUseWorkerThreads);
-                    _localPCs.SampleThreads(_workerThreads.Count, _inUseWorkerThreads);
-				}
-			}
-		}
-
-		/// <summary>
-		/// A worker thread method that processes work items from the work items queue.
-		/// </summary>
-		private void ProcessQueuedItems()
-		{
-            // Keep the entry of the dictionary as thread's variable to avoid the synchronization locks
-            // of the dictionary.
-            CurrentThreadEntry = _workerThreads[Thread.CurrentThread];
-
-            FireOnThreadInitialization();
-
-			try
-			{
-				bool bInUseWorkerThreadsWasIncremented = false;
-
-				// Process until shutdown.
-				while(!_shutdown)
-				{
-					// Update the last time this thread was seen alive.
-					// It's good for debugging.
-                    CurrentThreadEntry.IAmAlive();
-
-                    // The following block handles the when the MaxWorkerThreads has been
-                    // incremented by the user at run-time.
-                    // Double lock for quit.
-                    if (_workerThreads.Count > _stpStartInfo.MaxWorkerThreads)
-                    {
-                        lock (_workerThreads.SyncRoot)
-                        {
-                            if (_workerThreads.Count > _stpStartInfo.MaxWorkerThreads)
-                            {
-                                // Inform that the thread is quiting and then quit.
-                                // This method must be called within this lock or else
-                                // more threads will quit and the thread pool will go
-                                // below the lower limit.
-                                InformCompleted();
-                                break;
-                            }
-                        }
-                    }
-
-					// Wait for a work item, shutdown, or timeout
-					WorkItem workItem = Dequeue();
-
-					// Update the last time this thread was seen alive.
-					// It's good for debugging.
-                    CurrentThreadEntry.IAmAlive();
-
-					// On timeout or shut down.
-					if (null == workItem)
-					{
-						// Double lock for quit.
-                        if (_workerThreads.Count > _stpStartInfo.MinWorkerThreads)
-						{
-							lock(_workerThreads.SyncRoot)
-							{
-                                if (_workerThreads.Count > _stpStartInfo.MinWorkerThreads)
-								{
-									// Inform that the thread is quiting and then quit.
-									// This method must be called within this lock or else
-									// more threads will quit and the thread pool will go
-									// below the lower limit.
-									InformCompleted();
-									break;
-								}
-							}
-						}
-					}
-
-					// If we didn't quit then skip to the next iteration.
-					if (null == workItem)
-					{
-						continue;
-					}
-
-					try 
-					{
-						// Initialize the value to false
-						bInUseWorkerThreadsWasIncremented = false;
-
-                        // Set the Current Work Item of the thread.
-                        // Store the Current Work Item  before the workItem.StartingWorkItem() is called, 
-                        // so WorkItem.Cancel can work when the work item is between InQueue and InProgress 
-                        // states.
-                        // If the work item has been cancelled BEFORE the workItem.StartingWorkItem() 
-                        // (work item is in InQueue state) then workItem.StartingWorkItem() will return false.
-                        // If the work item has been cancelled AFTER the workItem.StartingWorkItem() then
-                        // (work item is in InProgress state) then the thread will be aborted
-                        CurrentThreadEntry.CurrentWorkItem = workItem;
-
-						// Change the state of the work item to 'in progress' if possible.
-						// We do it here so if the work item has been canceled we won't 
-						// increment the _inUseWorkerThreads.
-						// The cancel mechanism doesn't delete items from the queue,  
-						// it marks the work item as canceled, and when the work item
-						// is dequeued, we just skip it.
-						// If the post execute of work item is set to always or to
-						// call when the work item is canceled then the StartingWorkItem()
-						// will return true, so the post execute can run.
-						if (!workItem.StartingWorkItem())
-						{
-							continue;
-						}
-
-						// Execute the callback.  Make sure to accurately
-						// record how many callbacks are currently executing.
-						int inUseWorkerThreads = Interlocked.Increment(ref _inUseWorkerThreads);
-						_windowsPCs.SampleThreads(_workerThreads.Count, inUseWorkerThreads);
-                        _localPCs.SampleThreads(_workerThreads.Count, inUseWorkerThreads);
-
-						// Mark that the _inUseWorkerThreads incremented, so in the finally{}
-						// statement we will decrement it correctly.
-						bInUseWorkerThreadsWasIncremented = true;
-
-                        workItem.FireWorkItemStarted();
-
-						ExecuteWorkItem(workItem);
-					}
-					catch(Exception ex)
-					{
-                        ex.GetHashCode();
-						// Do nothing
-					}
-					finally
-					{
-						workItem.DisposeOfState();
-
-						// Set the CurrentWorkItem to null, since we 
-						// no longer run user's code.
-                        CurrentThreadEntry.CurrentWorkItem = null;
-
-						// Decrement the _inUseWorkerThreads only if we had 
-						// incremented it. Note the cancelled work items don't
-						// increment _inUseWorkerThreads.
-						if (bInUseWorkerThreadsWasIncremented)
-						{
-							int inUseWorkerThreads = Interlocked.Decrement(ref _inUseWorkerThreads);
-							_windowsPCs.SampleThreads(_workerThreads.Count, inUseWorkerThreads);
-                            _localPCs.SampleThreads(_workerThreads.Count, inUseWorkerThreads);
-						}
-
-						// Notify that the work item has been completed.
-						// WorkItemsGroup may enqueue their next work item.
-						workItem.FireWorkItemCompleted();
-
-						// Decrement the number of work items here so the idle 
-						// ManualResetEvent won't fluctuate.
-						DecrementWorkItemsCount();
-					}
-				}
-			} 
-			catch(ThreadAbortException tae)
-			{
-                tae.GetHashCode();
-                // Handle the abort exception gracfully.
-#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
-				Thread.ResetAbort();
-#endif
-            }
-			catch(Exception e)
-			{
-				Debug.Assert(null != e);
-			}
-			finally
-			{
-				InformCompleted();
-                FireOnThreadTermination();
-			}
-		}
-
-		private void ExecuteWorkItem(WorkItem workItem)
-		{
-			_windowsPCs.SampleWorkItemsWaitTime(workItem.WaitingTime);
-            _localPCs.SampleWorkItemsWaitTime(workItem.WaitingTime);
-			try
-			{
-				workItem.Execute();
-			}
-			finally
-			{
-				_windowsPCs.SampleWorkItemsProcessTime(workItem.ProcessTime);
-                _localPCs.SampleWorkItemsProcessTime(workItem.ProcessTime);
-			}
-		}
-
-
-		#endregion
-
-		#region Public Methods
-
-		private void ValidateWaitForIdle()
-		{
-            if (null != CurrentThreadEntry && CurrentThreadEntry.AssociatedSmartThreadPool == this)
-			{
-				throw new NotSupportedException(
-					"WaitForIdle cannot be called from a thread on its SmartThreadPool, it causes a deadlock");
-			}
-		}
-
-		internal static void ValidateWorkItemsGroupWaitForIdle(IWorkItemsGroup workItemsGroup)
-		{
-            if (null == CurrentThreadEntry)
-            {
-                return;
-            }
-
-            WorkItem workItem = CurrentThreadEntry.CurrentWorkItem;
-            ValidateWorkItemsGroupWaitForIdleImpl(workItemsGroup, workItem);
-			if ((null != workItemsGroup) &&
-                (null != workItem) &&
-                CurrentThreadEntry.CurrentWorkItem.WasQueuedBy(workItemsGroup))
-			{
-				throw new NotSupportedException("WaitForIdle cannot be called from a thread on its SmartThreadPool, it causes a deadlock");
-			}
-		}
-
-		[MethodImpl(MethodImplOptions.NoInlining)]
-		private static void ValidateWorkItemsGroupWaitForIdleImpl(IWorkItemsGroup workItemsGroup, WorkItem workItem)
-		{
-			if ((null != workItemsGroup) && 
-				(null != workItem) &&
-				workItem.WasQueuedBy(workItemsGroup))
-			{
-				throw new NotSupportedException("WaitForIdle cannot be called from a thread on its SmartThreadPool, it causes a deadlock");
-			}
-		}
-
-		/// <summary>
-		/// Force the SmartThreadPool to shutdown
-		/// </summary>
-		public void Shutdown()
-		{
-			Shutdown(true, 0);
-		}
-
-        /// <summary>
-        /// Force the SmartThreadPool to shutdown with timeout
-        /// </summary>
-        public void Shutdown(bool forceAbort, TimeSpan timeout)
-		{
-			Shutdown(forceAbort, (int)timeout.TotalMilliseconds);
-		}
-
-		/// <summary>
-		/// Empties the queue of work items and abort the threads in the pool.
-		/// </summary>
-		public void Shutdown(bool forceAbort, int millisecondsTimeout)
-		{
-			ValidateNotDisposed();
-
-			ISTPInstancePerformanceCounters pcs = _windowsPCs;
-
-			if (NullSTPInstancePerformanceCounters.Instance != _windowsPCs)
-			{
-				// Set the _pcs to "null" to stop updating the performance
-				// counters
-				_windowsPCs = NullSTPInstancePerformanceCounters.Instance;
-
-                pcs.Dispose();
-			}
-
-			Thread [] threads;
-			lock(_workerThreads.SyncRoot)
-			{
-				// Shutdown the work items queue
-				_workItemsQueue.Dispose();
-
-				// Signal the threads to exit
-				_shutdown = true;
-				_shuttingDownEvent.Set();
-
-				// Make a copy of the threads' references in the pool
-				threads = new Thread [_workerThreads.Count];
-				_workerThreads.Keys.CopyTo(threads, 0);
-			}
-
-			int millisecondsLeft = millisecondsTimeout;
-            Stopwatch stopwatch = Stopwatch.StartNew();
-            //DateTime start = DateTime.UtcNow;
-			bool waitInfinitely = (Timeout.Infinite == millisecondsTimeout);
-			bool timeout = false;
-
-			// Each iteration we update the time left for the timeout.
-			foreach(Thread thread in threads)
-			{
-				// Join don't work with negative numbers
-				if (!waitInfinitely && (millisecondsLeft < 0))
-				{
-					timeout = true;
-					break;
-				}
-
-				// Wait for the thread to terminate
-				bool success = thread.Join(millisecondsLeft);
-				if(!success)
-				{
-					timeout = true;
-					break;
-				}
-
-				if(!waitInfinitely)
-				{
-					// Update the time left to wait
-                    //TimeSpan ts = DateTime.UtcNow - start;
-                    millisecondsLeft = millisecondsTimeout - (int)stopwatch.ElapsedMilliseconds;
-				}
-			}
-
-			if (timeout && forceAbort)
-			{
-				// Abort the threads in the pool
-				foreach(Thread thread in threads)
-				{
-                    
-					if ((thread != null)
-#if !(_WINDOWS_CE)
-                        && thread.IsAlive
-#endif                        
-                        )
-					{
-						try 
-						{
-                            thread.Abort(); // Shutdown
-						}
-						catch(SecurityException e)
-						{
-                            e.GetHashCode();
-						}
-						catch(ThreadStateException ex)
-						{
-                            ex.GetHashCode();
-							// In case the thread has been terminated 
-							// after the check if it is alive.
-						}
-					}
-				}
-			}
-		}
-
-		/// <summary>
-		/// Wait for all work items to complete
-		/// </summary>
-        /// <param name="waitableResults">Array of work item result objects</param>
-		/// <returns>
-		/// true when every work item in workItemResults has completed; otherwise false.
-		/// </returns>
-		public static bool WaitAll(
-			IWaitableResult [] waitableResults)
-		{
-            return WaitAll(waitableResults, Timeout.Infinite, true);
-		}
-
-		/// <summary>
-		/// Wait for all work items to complete
-		/// </summary>
-        /// <param name="waitableResults">Array of work item result objects</param>
-		/// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param>
-		/// <param name="exitContext">
-		/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 
-		/// </param>
-		/// <returns>
-		/// true when every work item in workItemResults has completed; otherwise false.
-		/// </returns>
-		public static bool WaitAll(
-			IWaitableResult [] waitableResults,
-			TimeSpan timeout,
-			bool exitContext)
-		{
-            return WaitAll(waitableResults, (int)timeout.TotalMilliseconds, exitContext);
-		}
-
-		/// <summary>
-		/// Wait for all work items to complete
-		/// </summary>
-        /// <param name="waitableResults">Array of work item result objects</param>
-		/// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param>
-		/// <param name="exitContext">
-		/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 
-		/// </param>
-		/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
-		/// <returns>
-		/// true when every work item in workItemResults has completed; otherwise false.
-		/// </returns>
-		public static bool WaitAll(
-            IWaitableResult[] waitableResults,  
-			TimeSpan timeout,
-			bool exitContext,
-			WaitHandle cancelWaitHandle)
-		{
-            return WaitAll(waitableResults, (int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle);
-		}
-
-		/// <summary>
-		/// Wait for all work items to complete
-		/// </summary>
-        /// <param name="waitableResults">Array of work item result objects</param>
-		/// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
-		/// <param name="exitContext">
-		/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 
-		/// </param>
-		/// <returns>
-		/// true when every work item in workItemResults has completed; otherwise false.
-		/// </returns>
-		public static bool WaitAll(
-			IWaitableResult [] waitableResults,  
-			int millisecondsTimeout,
-			bool exitContext)
-		{
-            return WorkItem.WaitAll(waitableResults, millisecondsTimeout, exitContext, null);
-		}
-
-		/// <summary>
-		/// Wait for all work items to complete
-		/// </summary>
-        /// <param name="waitableResults">Array of work item result objects</param>
-		/// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
-		/// <param name="exitContext">
-		/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 
-		/// </param>
-		/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
-		/// <returns>
-		/// true when every work item in workItemResults has completed; otherwise false.
-		/// </returns>
-		public static bool WaitAll(
-            IWaitableResult[] waitableResults,  
-			int millisecondsTimeout,
-			bool exitContext,
-			WaitHandle cancelWaitHandle)
-		{
-            return WorkItem.WaitAll(waitableResults, millisecondsTimeout, exitContext, cancelWaitHandle);
-		}
-
-
-		/// <summary>
-		/// Waits for any of the work items in the specified array to complete, cancel, or timeout
-		/// </summary>
-        /// <param name="waitableResults">Array of work item result objects</param>
-		/// <returns>
-		/// The array index of the work item result that satisfied the wait, or WaitTimeout if any of the work items has been canceled.
-		/// </returns>
-		public static int WaitAny(
-			IWaitableResult [] waitableResults)
-		{
-            return WaitAny(waitableResults, Timeout.Infinite, true);
-		}
-
-		/// <summary>
-		/// Waits for any of the work items in the specified array to complete, cancel, or timeout
-		/// </summary>
-        /// <param name="waitableResults">Array of work item result objects</param>
-		/// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param>
-		/// <param name="exitContext">
-		/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 
-		/// </param>
-		/// <returns>
-		/// 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.
-		/// </returns>
-		public static int WaitAny(
-            IWaitableResult[] waitableResults,
-			TimeSpan timeout,
-			bool exitContext)
-		{
-            return WaitAny(waitableResults, (int)timeout.TotalMilliseconds, exitContext);
-		}
-
-		/// <summary>
-		/// Waits for any of the work items in the specified array to complete, cancel, or timeout
-		/// </summary>
-        /// <param name="waitableResults">Array of work item result objects</param>
-		/// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param>
-		/// <param name="exitContext">
-		/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 
-		/// </param>
-		/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
-		/// <returns>
-		/// 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.
-		/// </returns>
-		public static int WaitAny(
-			IWaitableResult [] waitableResults,
-			TimeSpan timeout,
-			bool exitContext,
-			WaitHandle cancelWaitHandle)
-		{
-            return WaitAny(waitableResults, (int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle);
-		}
-
-		/// <summary>
-		/// Waits for any of the work items in the specified array to complete, cancel, or timeout
-		/// </summary>
-        /// <param name="waitableResults">Array of work item result objects</param>
-		/// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
-		/// <param name="exitContext">
-		/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 
-		/// </param>
-		/// <returns>
-		/// 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.
-		/// </returns>
-		public static int WaitAny(
-			IWaitableResult [] waitableResults,  
-			int millisecondsTimeout,
-			bool exitContext)
-		{
-            return WorkItem.WaitAny(waitableResults, millisecondsTimeout, exitContext, null);
-		}
-
-		/// <summary>
-		/// Waits for any of the work items in the specified array to complete, cancel, or timeout
-		/// </summary>
-        /// <param name="waitableResults">Array of work item result objects</param>
-		/// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
-		/// <param name="exitContext">
-		/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 
-		/// </param>
-		/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
-		/// <returns>
-		/// 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.
-		/// </returns>
-		public static int WaitAny(
-			IWaitableResult [] waitableResults,  
-			int millisecondsTimeout,
-			bool exitContext,
-			WaitHandle cancelWaitHandle)
-		{
-            return WorkItem.WaitAny(waitableResults, millisecondsTimeout, exitContext, cancelWaitHandle);
-		}
-
-        /// <summary>
-        /// Creates a new WorkItemsGroup.
-        /// </summary>
-        /// <param name="concurrency">The number of work items that can be run concurrently</param>
-        /// <returns>A reference to the WorkItemsGroup</returns>
-		public IWorkItemsGroup CreateWorkItemsGroup(int concurrency)
-		{
-            IWorkItemsGroup workItemsGroup = new WorkItemsGroup(this, concurrency, _stpStartInfo);
-			return workItemsGroup;
-		}
-
-        /// <summary>
-        /// Creates a new WorkItemsGroup.
-        /// </summary>
-        /// <param name="concurrency">The number of work items that can be run concurrently</param>
-        /// <param name="wigStartInfo">A WorkItemsGroup configuration that overrides the default behavior</param>
-        /// <returns>A reference to the WorkItemsGroup</returns>
-		public IWorkItemsGroup CreateWorkItemsGroup(int concurrency, WIGStartInfo wigStartInfo)
-		{
-			IWorkItemsGroup workItemsGroup = new WorkItemsGroup(this, concurrency, wigStartInfo);
-			return workItemsGroup;
-		}
-
-        #region Fire Thread's Events
-
-        private void FireOnThreadInitialization()
-        {
-            if (null != _onThreadInitialization)
-            {
-                foreach (ThreadInitializationHandler tih in _onThreadInitialization.GetInvocationList())
-                {
-                    try
-                    {
-                        tih();
-                    }
-                    catch (Exception e)
-                    {
-                        e.GetHashCode();
-                        Debug.Assert(false);
-                        throw;
-                    }
-                }
-            }
-        }
-
-        private void FireOnThreadTermination()
-        {
-            if (null != _onThreadTermination)
-            {
-                foreach (ThreadTerminationHandler tth in _onThreadTermination.GetInvocationList())
-                {
-                    try
-                    {
-                        tth();
-                    }
-                    catch (Exception e)
-                    {
-                        e.GetHashCode();
-                        Debug.Assert(false);
-                        throw;
-                    }
-                }
-            }
-        }
-
-        #endregion
-
-        /// <summary>
-        /// This event is fired when a thread is created.
-        /// Use it to initialize a thread before the work items use it.
-        /// </summary>
-        public event ThreadInitializationHandler OnThreadInitialization
-        {
-            add { _onThreadInitialization += value; }
-            remove { _onThreadInitialization -= value; }
-        }
-
-        /// <summary>
-        /// This event is fired when a thread is terminating.
-        /// Use it for cleanup.
-        /// </summary>
-        public event ThreadTerminationHandler OnThreadTermination
-        {
-            add { _onThreadTermination += value; }
-            remove { _onThreadTermination -= value; }
-        }
-
-
-        internal void CancelAbortWorkItemsGroup(WorkItemsGroup wig)
-        {
-            foreach (ThreadEntry threadEntry in _workerThreads.Values)
-            {
-                WorkItem workItem = threadEntry.CurrentWorkItem;
-                if (null != workItem &&
-                    workItem.WasQueuedBy(wig) &&
-                    !workItem.IsCanceled)
-                {
-                    threadEntry.CurrentWorkItem.GetWorkItemResult().Cancel(true);
-                }
-            }
-        }
-
-        
-
-		#endregion
-
-		#region Properties
-
-		/// <summary>
-		/// Get/Set the lower limit of threads in the pool.
-		/// </summary>
-		public int MinThreads 
-		{ 
-			get 
-			{
-				ValidateNotDisposed();
-                return _stpStartInfo.MinWorkerThreads; 
-			}
-            set
-            {
-                Debug.Assert(value >= 0);
-                Debug.Assert(value <= _stpStartInfo.MaxWorkerThreads);
-                if (_stpStartInfo.MaxWorkerThreads < value)
-                {
-                    _stpStartInfo.MaxWorkerThreads = value;
-                }
-                _stpStartInfo.MinWorkerThreads = value;
-                StartOptimalNumberOfThreads();
-            }
-		}
-
-	    /// <summary>
-		/// Get/Set the upper limit of threads in the pool.
-		/// </summary>
-		public int MaxThreads 
-		{ 
-			get 
-			{
-				ValidateNotDisposed();
-                return _stpStartInfo.MaxWorkerThreads; 
-			} 
-
-			set 
-			{
-                Debug.Assert(value > 0);
-                Debug.Assert(value >= _stpStartInfo.MinWorkerThreads);
-                if (_stpStartInfo.MinWorkerThreads > value)
-                {
-                    _stpStartInfo.MinWorkerThreads = value;
-                }
-                _stpStartInfo.MaxWorkerThreads = value;
-                StartOptimalNumberOfThreads();
-            } 
-		}
-		/// <summary>
-		/// Get the number of threads in the thread pool.
-		/// Should be between the lower and the upper limits.
-		/// </summary>
-		public int ActiveThreads 
-		{ 
-			get 
-			{
-				ValidateNotDisposed();
-				return _workerThreads.Count; 
-			} 
-		}
-
-		/// <summary>
-		/// Get the number of busy (not idle) threads in the thread pool.
-		/// </summary>
-		public int InUseThreads 
-		{ 
-			get 
-			{ 
-				ValidateNotDisposed();
-				return _inUseWorkerThreads; 
-			} 
-		}
-
-        /// <summary>
-        /// Returns true if the current running work item has been cancelled.
-        /// Must be used within the work item's callback method.
-        /// The work item should sample this value in order to know if it
-        /// needs to quit before its completion.
-        /// </summary>
-        public static bool IsWorkItemCanceled
-        {
-            get
-            {
-                return CurrentThreadEntry.CurrentWorkItem.IsCanceled;
-            }
-        } 
-        
-        /// <summary>
-        /// Checks if the work item has been cancelled, and if yes then abort the thread.
-        /// Can be used with Cancel and timeout
-        /// </summary>
-        public static void AbortOnWorkItemCancel()
-        {
-            if (IsWorkItemCanceled)
-            {
-                Thread.CurrentThread.Abort();
-            }
-        }
-
-        /// <summary>
-        /// Thread Pool start information (readonly)
-        /// </summary>
-        public STPStartInfo STPStartInfo
-        {
-            get 
-            {
-                return _stpStartInfo.AsReadOnly(); 
-            }
-        }
-
-	    public bool IsShuttingdown
-	    {
-            get { return _shutdown;  }
-	    }
-
-        /// <summary>
-        /// Return the local calculated performance counters
-        /// Available only if STPStartInfo.EnableLocalPerformanceCounters is true.
-        /// </summary>
-        public ISTPPerformanceCountersReader PerformanceCountersReader
-        {
-            get { return (ISTPPerformanceCountersReader)_localPCs; }
-        }
-
-        #endregion
-
-        #region IDisposable Members
-
-        public void Dispose()
-        {
-            if (!_isDisposed)
-            {
-                if (!_shutdown)
-                {
-                    Shutdown();
-                }
-
-                if (null != _shuttingDownEvent)
-                {
-                    _shuttingDownEvent.Close();
-                    _shuttingDownEvent = null;
-                }
-                _workerThreads.Clear();
-                
-                if (null != _isIdleWaitHandle)
-                {
-                    _isIdleWaitHandle.Close();
-                    _isIdleWaitHandle = null;
-                }
-
-                _isDisposed = true;
-            }
-        }
-
-        private void ValidateNotDisposed()
-        {
-            if(_isDisposed)
-            {
-                throw new ObjectDisposedException(GetType().ToString(), "The SmartThreadPool has been shutdown");
-            }
-        }
-        #endregion
-
-        #region WorkItemsGroupBase Overrides
-
-        /// <summary>
-        /// Get/Set the maximum number of work items that execute cocurrency on the thread pool
-        /// </summary>
-        public override int Concurrency
-	    {
-	        get { return MaxThreads; }
-	        set { MaxThreads = value; }
-	    }
-
-	    /// <summary>
-	    /// Get the number of work items in the queue.
-	    /// </summary>
-	    public override int WaitingCallbacks
-	    {
-	        get
-	        {
-	            ValidateNotDisposed();
-	            return _workItemsQueue.Count;
-	        }
-	    }
-
-        /// <summary>
-        /// Get an array with all the state objects of the currently running items.
-        /// The array represents a snap shot and impact performance.
-        /// </summary>
-        public override object[] GetStates()
-        {
-            object[] states = _workItemsQueue.GetStates();
-            return states;
-        }
-
-        /// <summary>
-        /// WorkItemsGroup start information (readonly)
-        /// </summary>
-        public override WIGStartInfo WIGStartInfo
-        {
-            get { return _stpStartInfo.AsReadOnly(); }
-        }
-
-	    /// <summary>
-        /// Start the thread pool if it was started suspended.
-        /// If it is already running, this method is ignored.
-        /// </summary>
-        public override void Start()
-        {
-            if (!_isSuspended)
-            {
-                return;
-            }
-            _isSuspended = false;
-
-            ICollection workItemsGroups = _workItemsGroups.Values;
-            foreach (WorkItemsGroup workItemsGroup in workItemsGroups)
-            {
-                workItemsGroup.OnSTPIsStarting();
-            }
-
-            StartOptimalNumberOfThreads();
-        }
-
-        /// <summary>
-        /// Cancel all work items using thread abortion
-        /// </summary>
-        /// <param name="abortExecution">True to stop work items by raising ThreadAbortException</param>
-        public override void Cancel(bool abortExecution)
-        {
-            _canceledSmartThreadPool.IsCanceled = true;
-            _canceledSmartThreadPool = new CanceledWorkItemsGroup();
-
-            ICollection workItemsGroups = _workItemsGroups.Values;
-            foreach (WorkItemsGroup workItemsGroup in workItemsGroups)
-            {
-                workItemsGroup.Cancel(abortExecution);
-            }
-
-            if (abortExecution)
-            {
-                foreach (ThreadEntry threadEntry in _workerThreads.Values)
-                {
-                    WorkItem workItem = threadEntry.CurrentWorkItem;
-                    if (null != workItem &&
-                        threadEntry.AssociatedSmartThreadPool == this &&
-                        !workItem.IsCanceled)
-                    {
-                        threadEntry.CurrentWorkItem.GetWorkItemResult().Cancel(true);
-                    }
-                }
-            }
-        }
-
-	    /// <summary>
-        /// Wait for the thread pool to be idle
-        /// </summary>
-        public override bool WaitForIdle(int millisecondsTimeout)
-        {
-            ValidateWaitForIdle();
-            return STPEventWaitHandle.WaitOne(_isIdleWaitHandle, millisecondsTimeout, false);
-        }
-
-        /// <summary>
-        /// This event is fired when all work items are completed.
-        /// (When IsIdle changes to true)
-        /// This event only work on WorkItemsGroup. On SmartThreadPool
-        /// it throws the NotImplementedException.
-        /// </summary>
-        public override event WorkItemsGroupIdleHandler OnIdle
-        {
-            add
-            {
-                throw new NotImplementedException("This event is not implemented in the SmartThreadPool class. Please create a WorkItemsGroup in order to use this feature.");
-                //_onIdle += value;
-            }
-            remove
-            {
-                throw new NotImplementedException("This event is not implemented in the SmartThreadPool class. Please create a WorkItemsGroup in order to use this feature.");
-                //_onIdle -= value;
-            }
-        }
-
-	    internal override void PreQueueWorkItem()
-        {
-            ValidateNotDisposed();   
-        }
-
-        #endregion
-
-        #region Join, Choice, Pipe, etc.
-
-        /// <summary>
-        /// Executes all actions in parallel.
-        /// Returns when they all finish.
-        /// </summary>
-        /// <param name="actions">Actions to execute</param>
-        public void Join(IEnumerable<Action> actions)
-        {
-            WIGStartInfo wigStartInfo = new WIGStartInfo { StartSuspended = true };
-            IWorkItemsGroup workItemsGroup = CreateWorkItemsGroup(int.MaxValue, wigStartInfo);
-            foreach (Action action in actions)
-            {
-                workItemsGroup.QueueWorkItem(action);
-            }
-            workItemsGroup.Start();
-            workItemsGroup.WaitForIdle();
-        }
-
-        /// <summary>
-        /// Executes all actions in parallel.
-        /// Returns when they all finish.
-        /// </summary>
-        /// <param name="actions">Actions to execute</param>
-        public void Join(params Action[] actions)
-        {
-            Join((IEnumerable<Action>)actions);
-        }
-
-        private class ChoiceIndex
-        {
-            public int _index = -1;
-        }
-
-        /// <summary>
-        /// Executes all actions in parallel
-        /// Returns when the first one completes
-        /// </summary>
-        /// <param name="actions">Actions to execute</param>
-        public int Choice(IEnumerable<Action> actions)
-        {
-            WIGStartInfo wigStartInfo = new WIGStartInfo { StartSuspended = true };
-            IWorkItemsGroup workItemsGroup = CreateWorkItemsGroup(int.MaxValue, wigStartInfo);
-
-            ManualResetEvent anActionCompleted = new ManualResetEvent(false);
-
-            ChoiceIndex choiceIndex = new ChoiceIndex();
-            
-            int i = 0;
-            foreach (Action action in actions)
-            {
-                Action act = action;
-                int value = i;
-                workItemsGroup.QueueWorkItem(() => { act(); Interlocked.CompareExchange(ref choiceIndex._index, value, -1); anActionCompleted.Set(); });
-                ++i;
-            }
-	        workItemsGroup.Start();
-            anActionCompleted.WaitOne();
-
-            return choiceIndex._index;
-        }
-
-        /// <summary>
-        /// Executes all actions in parallel
-        /// Returns when the first one completes
-        /// </summary>
-        /// <param name="actions">Actions to execute</param>
-        public int Choice(params Action[] actions)
-	    {
-            return Choice((IEnumerable<Action>)actions);
-        }
-
-        /// <summary>
-        /// Executes actions in sequence asynchronously.
-        /// Returns immediately.
-        /// </summary>
-        /// <param name="pipeState">A state context that passes </param>
-        /// <param name="actions">Actions to execute in the order they should run</param>
-        public void Pipe<T>(T pipeState, IEnumerable<Action<T>> actions)
-        {
-            WIGStartInfo wigStartInfo = new WIGStartInfo { StartSuspended = true };
-            IWorkItemsGroup workItemsGroup = CreateWorkItemsGroup(1, wigStartInfo);
-            foreach (Action<T> action in actions)
-            {
-                Action<T> act = action;
-                workItemsGroup.QueueWorkItem(() => act(pipeState));
-            }
-            workItemsGroup.Start();
-            workItemsGroup.WaitForIdle();
-        }
-
-        /// <summary>
-        /// Executes actions in sequence asynchronously.
-        /// Returns immediately.
-        /// </summary>
-        /// <param name="pipeState"></param>
-        /// <param name="actions">Actions to execute in the order they should run</param>
-        public void Pipe<T>(T pipeState, params Action<T>[] actions)
-        {
-            Pipe(pipeState, (IEnumerable<Action<T>>)actions);
-        }
-        #endregion
-	}
-	#endregion
-}
+#region Release History
+
+// Smart Thread Pool
+// 7 Aug 2004 - Initial release
+//
+// 14 Sep 2004 - Bug fixes 
+//
+// 15 Oct 2004 - Added new features
+//		- Work items return result.
+//		- Support waiting synchronization for multiple work items.
+//		- Work items can be cancelled.
+//		- Passage of the caller thread’s context to the thread in the pool.
+//		- Minimal usage of WIN32 handles.
+//		- Minor bug fixes.
+//
+// 26 Dec 2004 - Changes:
+//		- Removed static constructors.
+//      - Added finalizers.
+//		- Changed Exceptions so they are serializable.
+//		- Fixed the bug in one of the SmartThreadPool constructors.
+//		- Changed the SmartThreadPool.WaitAll() so it will support any number of waiters. 
+//        The SmartThreadPool.WaitAny() is still limited by the .NET Framework.
+//		- Added PostExecute with options on which cases to call it.
+//      - Added option to dispose of the state objects.
+//      - Added a WaitForIdle() method that waits until the work items queue is empty.
+//      - Added an STPStartInfo class for the initialization of the thread pool.
+//      - Changed exception handling so if a work item throws an exception it 
+//        is rethrown at GetResult(), rather then firing an UnhandledException event.
+//        Note that PostExecute exception are always ignored.
+//
+// 25 Mar 2005 - Changes:
+//		- Fixed lost of work items bug
+//
+// 3 Jul 2005: Changes.
+//      - Fixed bug where Enqueue() throws an exception because PopWaiter() returned null, hardly reconstructed. 
+//
+// 16 Aug 2005: Changes.
+//		- Fixed bug where the InUseThreads becomes negative when canceling work items. 
+//
+// 31 Jan 2006 - Changes:
+//		- Added work items priority
+//		- Removed support of chained delegates in callbacks and post executes (nobody really use this)
+//		- Added work items groups
+//		- Added work items groups idle event
+//		- Changed SmartThreadPool.WaitAll() behavior so when it gets empty array
+//		  it returns true rather then throwing an exception.
+//		- Added option to start the STP and the WIG as suspended
+//		- Exception behavior changed, the real exception is returned by an 
+//		  inner exception
+//		- Added option to keep the Http context of the caller thread. (Thanks to Steven T.)
+//		- Added performance counters
+//		- Added priority to the threads in the pool
+//
+// 13 Feb 2006 - Changes:
+//		- Added a call to the dispose of the Performance Counter so
+//		  their won't be a Performance Counter leak.
+//		- Added exception catch in case the Performance Counters cannot 
+//		  be created.
+//
+// 17 May 2008 - Changes:
+//      - Changed the dispose behavior and removed the Finalizers.
+//      - Enabled the change of the MaxThreads and MinThreads at run time.
+//      - Enabled the change of the Concurrency of a IWorkItemsGroup at run 
+//        time If the IWorkItemsGroup is a SmartThreadPool then the Concurrency 
+//        refers to the MaxThreads. 
+//      - Improved the cancel behavior.
+//      - Added events for thread creation and termination. 
+//      - Fixed the HttpContext context capture.
+//      - Changed internal collections so they use generic collections
+//      - Added IsIdle flag to the SmartThreadPool and IWorkItemsGroup
+//      - Added support for WinCE
+//      - Added support for Action<T> and Func<T>
+//
+// 07 April 2009 - Changes:
+//      - Added support for Silverlight and Mono
+//      - Added Join, Choice, and Pipe to SmartThreadPool.
+//      - Added local performance counters (for Mono, Silverlight, and WindowsCE)
+//      - Changed duration measures from DateTime.Now to Stopwatch.
+//      - Queues changed from System.Collections.Queue to System.Collections.Generic.LinkedList<T>.
+//
+// 21 December 2009 - Changes:
+//      - Added work item timeout (passive)
+//
+// 20 August 2012 - Changes:
+//      - Added set name to threads
+//      - Fixed the WorkItemsQueue.Dequeue. 
+//        Replaced while (!Monitor.TryEnter(this)); with lock(this) { ... }
+//      - Fixed SmartThreadPool.Pipe
+//      - Added IsBackground option to threads
+//      - Added ApartmentState to threads
+//      - Fixed thread creation when queuing many work items at the same time.
+//
+// 24 August 2012 - Changes:
+//      - Enabled cancel abort after cancel. See: http://smartthreadpool.codeplex.com/discussions/345937 by alecswan
+//      - Added option to set MaxStackSize of threads 
+
+#endregion
+
+using System;
+using System.Security;
+using System.Threading;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+
+using Amib.Threading.Internal;
+
+namespace Amib.Threading
+{
+	#region SmartThreadPool class
+	/// <summary>
+	/// Smart thread pool class.
+	/// </summary>
+	public partial class SmartThreadPool : WorkItemsGroupBase, IDisposable
+	{
+		#region Public Default Constants
+
+		/// <summary>
+		/// Default minimum number of threads the thread pool contains. (0)
+		/// </summary>
+		public const int DefaultMinWorkerThreads = 0;
+
+		/// <summary>
+		/// Default maximum number of threads the thread pool contains. (25)
+		/// </summary>
+		public const int DefaultMaxWorkerThreads = 25;
+
+		/// <summary>
+		/// Default idle timeout in milliseconds. (One minute)
+		/// </summary>
+		public const int DefaultIdleTimeout = 60*1000; // One minute
+
+		/// <summary>
+		/// Indicate to copy the security context of the caller and then use it in the call. (false)
+		/// </summary>
+		public const bool DefaultUseCallerCallContext = false; 
+
+		/// <summary>
+		/// Indicate to copy the HTTP context of the caller and then use it in the call. (false)
+		/// </summary>
+		public const bool DefaultUseCallerHttpContext = false;
+
+		/// <summary>
+		/// Indicate to dispose of the state objects if they support the IDispose interface. (false)
+		/// </summary>
+		public const bool DefaultDisposeOfStateObjects = false; 
+
+		/// <summary>
+        /// The default option to run the post execute (CallToPostExecute.Always)
+		/// </summary>
+		public const CallToPostExecute DefaultCallToPostExecute = CallToPostExecute.Always;
+
+		/// <summary>
+		/// The default post execute method to run. (None)
+		/// When null it means not to call it.
+		/// </summary>
+		public static readonly PostExecuteWorkItemCallback DefaultPostExecuteWorkItemCallback;
+
+		/// <summary>
+        /// The default work item priority (WorkItemPriority.Normal)
+		/// </summary>
+		public const WorkItemPriority DefaultWorkItemPriority = WorkItemPriority.Normal;
+
+		/// <summary>
+		/// The default is to work on work items as soon as they arrive
+		/// and not to wait for the start. (false)
+		/// </summary>
+		public const bool DefaultStartSuspended = false;
+
+		/// <summary>
+        /// The default name to use for the performance counters instance. (null)
+		/// </summary>
+		public static readonly string DefaultPerformanceCounterInstanceName;
+
+#if !(WINDOWS_PHONE)
+
+		/// <summary>
+        /// The default thread priority (ThreadPriority.Normal)
+		/// </summary>
+		public const ThreadPriority DefaultThreadPriority = ThreadPriority.Normal;
+#endif
+        /// <summary>
+        /// The default thread pool name. (SmartThreadPool)
+        /// </summary>
+        public const string DefaultThreadPoolName = "SmartThreadPool";
+
+        /// <summary>
+        /// The default Max Stack Size. (SmartThreadPool)
+        /// </summary>
+        public static readonly int? DefaultMaxStackSize = null;
+
+        /// <summary>
+        /// The default fill state with params. (false)
+        /// It is relevant only to QueueWorkItem of Action&lt;...&gt;/Func&lt;...&gt;
+        /// </summary>
+        public const bool DefaultFillStateWithArgs = false;
+
+        /// <summary>
+        /// The default thread backgroundness. (true)
+        /// </summary>
+        public const bool DefaultAreThreadsBackground = true;
+
+#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
+        /// <summary>
+        /// The default apartment state of a thread in the thread pool. 
+        /// The default is ApartmentState.Unknown which means the STP will not 
+        /// set the apartment of the thread. It will use the .NET default.
+        /// </summary>
+        public const ApartmentState DefaultApartmentState = ApartmentState.Unknown;
+#endif
+
+		#endregion
+
+        #region Member Variables
+
+		/// <summary>
+		/// Dictionary of all the threads in the thread pool.
+		/// </summary>
+        private readonly SynchronizedDictionary<Thread, ThreadEntry> _workerThreads = new SynchronizedDictionary<Thread, ThreadEntry>();
+
+		/// <summary>
+		/// Queue of work items.
+		/// </summary>
+		private readonly WorkItemsQueue _workItemsQueue = new WorkItemsQueue();
+
+		/// <summary>
+		/// Count the work items handled.
+		/// Used by the performance counter.
+		/// </summary>
+		private int _workItemsProcessed;
+
+		/// <summary>
+		/// Number of threads that currently work (not idle).
+		/// </summary>
+		private int _inUseWorkerThreads;
+
+        /// <summary>
+        /// Stores a copy of the original STPStartInfo.
+        /// It is used to change the MinThread and MaxThreads
+        /// </summary>
+        private STPStartInfo _stpStartInfo;
+
+		/// <summary>
+		/// Total number of work items that are stored in the work items queue 
+		/// plus the work items that the threads in the pool are working on.
+		/// </summary>
+		private int _currentWorkItemsCount;
+
+		/// <summary>
+		/// Signaled when the thread pool is idle, i.e. no thread is busy
+		/// and the work items queue is empty
+		/// </summary>
+		//private ManualResetEvent _isIdleWaitHandle = new ManualResetEvent(true);
+		private ManualResetEvent _isIdleWaitHandle = EventWaitHandleFactory.CreateManualResetEvent(true);
+
+		/// <summary>
+		/// An event to signal all the threads to quit immediately.
+		/// </summary>
+		//private ManualResetEvent _shuttingDownEvent = new ManualResetEvent(false);
+		private ManualResetEvent _shuttingDownEvent = EventWaitHandleFactory.CreateManualResetEvent(false);
+
+        /// <summary>
+        /// A flag to indicate if the Smart Thread Pool is now suspended.
+        /// </summary>
+        private bool _isSuspended;
+
+		/// <summary>
+		/// A flag to indicate the threads to quit.
+		/// </summary>
+		private bool _shutdown;
+
+		/// <summary>
+		/// Counts the threads created in the pool.
+		/// It is used to name the threads.
+		/// </summary>
+		private int _threadCounter;
+
+		/// <summary>
+		/// Indicate that the SmartThreadPool has been disposed
+		/// </summary>
+		private bool _isDisposed;
+
+		/// <summary>
+		/// Holds all the WorkItemsGroup instaces that have at least one 
+		/// work item int the SmartThreadPool
+		/// This variable is used in case of Shutdown
+		/// </summary>
+        private readonly SynchronizedDictionary<IWorkItemsGroup, IWorkItemsGroup> _workItemsGroups = new SynchronizedDictionary<IWorkItemsGroup, IWorkItemsGroup>();
+
+        /// <summary>
+        /// A common object for all the work items int the STP
+        /// so we can mark them to cancel in O(1)
+        /// </summary>
+        private CanceledWorkItemsGroup _canceledSmartThreadPool = new CanceledWorkItemsGroup();
+
+        /// <summary>
+        /// Windows STP performance counters
+        /// </summary>
+        private ISTPInstancePerformanceCounters _windowsPCs = NullSTPInstancePerformanceCounters.Instance;
+
+        /// <summary>
+        /// Local STP performance counters
+        /// </summary>
+        private ISTPInstancePerformanceCounters _localPCs = NullSTPInstancePerformanceCounters.Instance;
+
+
+#if (WINDOWS_PHONE) 
+        private static readonly Dictionary<int, ThreadEntry> _threadEntries = new Dictionary<int, ThreadEntry>();
+#elif (_WINDOWS_CE)
+        private static LocalDataStoreSlot _threadEntrySlot = Thread.AllocateDataSlot();
+#else
+        [ThreadStatic]
+        private static ThreadEntry _threadEntry;
+
+#endif
+
+        /// <summary>
+        /// An event to call after a thread is created, but before 
+        /// it's first use.
+        /// </summary>
+        private event ThreadInitializationHandler _onThreadInitialization;
+
+        /// <summary>
+        /// An event to call when a thread is about to exit, after 
+        /// it is no longer belong to the pool.
+        /// </summary>
+        private event ThreadTerminationHandler _onThreadTermination;
+
+        #endregion
+
+        #region Per thread properties
+
+        /// <summary>
+        /// A reference to the current work item a thread from the thread pool 
+        /// is executing.
+        /// </summary>
+        internal static ThreadEntry CurrentThreadEntry
+        {
+#if (WINDOWS_PHONE)
+            get
+            {
+                lock(_threadEntries)
+                {
+                    ThreadEntry threadEntry;
+                    if (_threadEntries.TryGetValue(Thread.CurrentThread.ManagedThreadId, out threadEntry))
+                    {
+                        return threadEntry;
+                    }
+                }
+                return null;
+            }
+            set
+            {
+                lock(_threadEntries)
+                {
+                    _threadEntries[Thread.CurrentThread.ManagedThreadId] = value;
+                }
+            }
+#elif (_WINDOWS_CE)
+            get
+            {
+                //Thread.CurrentThread.ManagedThreadId
+                return Thread.GetData(_threadEntrySlot) as ThreadEntry;
+            }
+            set
+            {
+                Thread.SetData(_threadEntrySlot, value);
+            }
+#else
+            get
+            {
+                return _threadEntry;
+            }
+            set
+            {
+                _threadEntry = value;
+            }
+#endif
+        }
+        #endregion
+
+        #region Construction and Finalization
+
+        /// <summary>
+		/// Constructor
+		/// </summary>
+		public SmartThreadPool()
+		{
+            _stpStartInfo = new STPStartInfo();
+            Initialize();
+		}
+
+		/// <summary>
+		/// Constructor
+		/// </summary>
+		/// <param name="idleTimeout">Idle timeout in milliseconds</param>
+		public SmartThreadPool(int idleTimeout)
+		{
+            _stpStartInfo = new STPStartInfo
+            {
+                IdleTimeout = idleTimeout,
+            };
+			Initialize();
+		}
+
+		/// <summary>
+		/// Constructor
+		/// </summary>
+		/// <param name="idleTimeout">Idle timeout in milliseconds</param>
+		/// <param name="maxWorkerThreads">Upper limit of threads in the pool</param>
+		public SmartThreadPool(
+			int idleTimeout,
+			int maxWorkerThreads)
+		{
+            _stpStartInfo = new STPStartInfo
+            {
+                IdleTimeout = idleTimeout,
+                MaxWorkerThreads = maxWorkerThreads,
+            };
+			Initialize();
+		}
+
+		/// <summary>
+		/// Constructor
+		/// </summary>
+		/// <param name="idleTimeout">Idle timeout in milliseconds</param>
+		/// <param name="maxWorkerThreads">Upper limit of threads in the pool</param>
+		/// <param name="minWorkerThreads">Lower limit of threads in the pool</param>
+		public SmartThreadPool(
+			int idleTimeout,
+			int maxWorkerThreads,
+			int minWorkerThreads)
+		{
+            _stpStartInfo = new STPStartInfo
+            {
+                IdleTimeout = idleTimeout,
+                MaxWorkerThreads = maxWorkerThreads,
+                MinWorkerThreads = minWorkerThreads,
+            };
+			Initialize();
+		}
+
+        /// <summary>
+        /// Constructor
+        /// </summary>
+        /// <param name="stpStartInfo">A SmartThreadPool configuration that overrides the default behavior</param>
+		public SmartThreadPool(STPStartInfo stpStartInfo)
+		{
+			_stpStartInfo = new STPStartInfo(stpStartInfo);
+			Initialize();
+		}
+
+		private void Initialize()
+		{
+            Name = _stpStartInfo.ThreadPoolName;
+			ValidateSTPStartInfo();
+
+            // _stpStartInfoRW stores a read/write copy of the STPStartInfo.
+            // Actually only MaxWorkerThreads and MinWorkerThreads are overwritten
+
+            _isSuspended = _stpStartInfo.StartSuspended;
+
+#if (_WINDOWS_CE) || (_SILVERLIGHT) || (_MONO) || (WINDOWS_PHONE)
+			if (null != _stpStartInfo.PerformanceCounterInstanceName)
+			{
+                throw new NotSupportedException("Performance counters are not implemented for Compact Framework/Silverlight/Mono, instead use StpStartInfo.EnableLocalPerformanceCounters");
+            }
+#else
+            if (null != _stpStartInfo.PerformanceCounterInstanceName)
+            {
+                try
+                {
+                    _windowsPCs = new STPInstancePerformanceCounters(_stpStartInfo.PerformanceCounterInstanceName);
+                }
+                catch (Exception e)
+                {
+                    Debug.WriteLine("Unable to create Performance Counters: " + e);
+                    _windowsPCs = NullSTPInstancePerformanceCounters.Instance;
+                }
+            }
+#endif
+
+            if (_stpStartInfo.EnableLocalPerformanceCounters)
+            {
+                _localPCs = new LocalSTPInstancePerformanceCounters();
+            }
+
+		    // If the STP is not started suspended then start the threads.
+            if (!_isSuspended)
+            {
+                StartOptimalNumberOfThreads();
+            }
+		}
+
+		private void StartOptimalNumberOfThreads()
+		{
+			int threadsCount = Math.Max(_workItemsQueue.Count, _stpStartInfo.MinWorkerThreads);
+            threadsCount = Math.Min(threadsCount, _stpStartInfo.MaxWorkerThreads);
+            threadsCount -= _workerThreads.Count;
+            if (threadsCount > 0)
+            {
+                StartThreads(threadsCount);
+            }
+		}
+
+		private void ValidateSTPStartInfo()
+		{
+            if (_stpStartInfo.MinWorkerThreads < 0)
+			{
+				throw new ArgumentOutOfRangeException(
+					"MinWorkerThreads", "MinWorkerThreads cannot be negative");
+			}
+
+            if (_stpStartInfo.MaxWorkerThreads <= 0)
+			{
+				throw new ArgumentOutOfRangeException(
+					"MaxWorkerThreads", "MaxWorkerThreads must be greater than zero");
+			}
+
+            if (_stpStartInfo.MinWorkerThreads > _stpStartInfo.MaxWorkerThreads)
+			{
+				throw new ArgumentOutOfRangeException(
+					"MinWorkerThreads, maxWorkerThreads", 
+					"MaxWorkerThreads must be greater or equal to MinWorkerThreads");
+			}
+		}
+
+		private static void ValidateCallback(Delegate callback)
+		{
+			if(callback.GetInvocationList().Length > 1)
+			{
+				throw new NotSupportedException("SmartThreadPool doesn't support delegates chains");
+			}
+		}
+
+		#endregion
+
+		#region Thread Processing
+
+		/// <summary>
+		/// Waits on the queue for a work item, shutdown, or timeout.
+		/// </summary>
+		/// <returns>
+		/// Returns the WaitingCallback or null in case of timeout or shutdown.
+		/// </returns>
+		private WorkItem Dequeue()
+		{
+			WorkItem workItem =
+                _workItemsQueue.DequeueWorkItem(_stpStartInfo.IdleTimeout, _shuttingDownEvent);
+
+			return workItem;
+		}
+
+		/// <summary>
+		/// Put a new work item in the queue
+		/// </summary>
+		/// <param name="workItem">A work item to queue</param>
+		internal override void Enqueue(WorkItem workItem)
+		{
+			// Make sure the workItem is not null
+			Debug.Assert(null != workItem);
+
+			IncrementWorkItemsCount();
+
+            workItem.CanceledSmartThreadPool = _canceledSmartThreadPool;
+			_workItemsQueue.EnqueueWorkItem(workItem);
+			workItem.WorkItemIsQueued();
+
+			// If all the threads are busy then try to create a new one
+			if (_currentWorkItemsCount > _workerThreads.Count) 
+			{
+				StartThreads(1);
+			}
+		}
+
+		private void IncrementWorkItemsCount()
+		{
+			_windowsPCs.SampleWorkItems(_workItemsQueue.Count, _workItemsProcessed);
+            _localPCs.SampleWorkItems(_workItemsQueue.Count, _workItemsProcessed);
+
+			int count = Interlocked.Increment(ref _currentWorkItemsCount);
+			//Trace.WriteLine("WorkItemsCount = " + _currentWorkItemsCount.ToString());
+			if (count == 1) 
+			{
+                IsIdle = false;
+                _isIdleWaitHandle.Reset();
+			}
+		}
+
+		private void DecrementWorkItemsCount()
+		{
+            int count = Interlocked.Decrement(ref _currentWorkItemsCount);
+            //Trace.WriteLine("WorkItemsCount = " + _currentWorkItemsCount.ToString());
+            if (count == 0)
+            {
+                IsIdle = true;
+                _isIdleWaitHandle.Set();
+            }
+
+            Interlocked.Increment(ref _workItemsProcessed);
+
+            if (!_shutdown)
+            {
+			    // The counter counts even if the work item was cancelled
+			    _windowsPCs.SampleWorkItems(_workItemsQueue.Count, _workItemsProcessed);
+                _localPCs.SampleWorkItems(_workItemsQueue.Count, _workItemsProcessed);
+            }
+
+		}
+
+		internal void RegisterWorkItemsGroup(IWorkItemsGroup workItemsGroup)
+		{
+			_workItemsGroups[workItemsGroup] = workItemsGroup;
+		}
+
+		internal void UnregisterWorkItemsGroup(IWorkItemsGroup workItemsGroup)
+		{
+			if (_workItemsGroups.Contains(workItemsGroup))
+			{
+				_workItemsGroups.Remove(workItemsGroup);
+			}
+		}
+
+		/// <summary>
+		/// Inform that the current thread is about to quit or quiting.
+		/// The same thread may call this method more than once.
+		/// </summary>
+		private void InformCompleted()
+		{
+			// There is no need to lock the two methods together 
+			// since only the current thread removes itself
+			// and the _workerThreads is a synchronized dictionary
+			if (_workerThreads.Contains(Thread.CurrentThread))
+			{
+				_workerThreads.Remove(Thread.CurrentThread);
+				_windowsPCs.SampleThreads(_workerThreads.Count, _inUseWorkerThreads);
+                _localPCs.SampleThreads(_workerThreads.Count, _inUseWorkerThreads);
+			}
+		}
+
+		/// <summary>
+		/// Starts new threads
+		/// </summary>
+		/// <param name="threadsCount">The number of threads to start</param>
+		private void StartThreads(int threadsCount)
+		{
+            if (_isSuspended)
+			{
+				return;
+			}
+
+			lock(_workerThreads.SyncRoot)
+			{
+				// Don't start threads on shut down
+				if (_shutdown)
+				{
+					return;
+				}
+
+				for(int i = 0; i < threadsCount; ++i)
+				{
+					// Don't create more threads then the upper limit
+                    if (_workerThreads.Count >= _stpStartInfo.MaxWorkerThreads)
+					{
+						return;
+					}
+
+                    // Create a new thread
+
+#if (_SILVERLIGHT) || (WINDOWS_PHONE)
+					Thread workerThread = new Thread(ProcessQueuedItems);
+#else
+                    Thread workerThread =
+                        _stpStartInfo.MaxStackSize.HasValue
+                        ? new Thread(ProcessQueuedItems, _stpStartInfo.MaxStackSize.Value)
+                        : new Thread(ProcessQueuedItems);
+#endif
+					// Configure the new thread and start it
+					workerThread.Name = "STP " + Name + " Thread #" + _threadCounter;
+                    workerThread.IsBackground = _stpStartInfo.AreThreadsBackground;
+
+#if !(_SILVERLIGHT) && !(_WINDOWS_CE) && !(WINDOWS_PHONE)
+                    if (_stpStartInfo.ApartmentState != ApartmentState.Unknown)
+                    {
+                        workerThread.SetApartmentState(_stpStartInfo.ApartmentState);
+                    }
+#endif
+
+#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
+                    workerThread.Priority = _stpStartInfo.ThreadPriority;
+#endif
+                    workerThread.Start();
+					++_threadCounter;
+
+                    // Add it to the dictionary and update its creation time.
+                    _workerThreads[workerThread] = new ThreadEntry(this);
+
+					_windowsPCs.SampleThreads(_workerThreads.Count, _inUseWorkerThreads);
+                    _localPCs.SampleThreads(_workerThreads.Count, _inUseWorkerThreads);
+				}
+			}
+		}
+
+		/// <summary>
+		/// A worker thread method that processes work items from the work items queue.
+		/// </summary>
+		private void ProcessQueuedItems()
+		{
+            // Keep the entry of the dictionary as thread's variable to avoid the synchronization locks
+            // of the dictionary.
+            CurrentThreadEntry = _workerThreads[Thread.CurrentThread];
+
+            FireOnThreadInitialization();
+
+			try
+			{
+				bool bInUseWorkerThreadsWasIncremented = false;
+
+				// Process until shutdown.
+				while(!_shutdown)
+				{
+					// Update the last time this thread was seen alive.
+					// It's good for debugging.
+                    CurrentThreadEntry.IAmAlive();
+
+                    // The following block handles the when the MaxWorkerThreads has been
+                    // incremented by the user at run-time.
+                    // Double lock for quit.
+                    if (_workerThreads.Count > _stpStartInfo.MaxWorkerThreads)
+                    {
+                        lock (_workerThreads.SyncRoot)
+                        {
+                            if (_workerThreads.Count > _stpStartInfo.MaxWorkerThreads)
+                            {
+                                // Inform that the thread is quiting and then quit.
+                                // This method must be called within this lock or else
+                                // more threads will quit and the thread pool will go
+                                // below the lower limit.
+                                InformCompleted();
+                                break;
+                            }
+                        }
+                    }
+
+					// Wait for a work item, shutdown, or timeout
+					WorkItem workItem = Dequeue();
+
+					// Update the last time this thread was seen alive.
+					// It's good for debugging.
+                    CurrentThreadEntry.IAmAlive();
+
+					// On timeout or shut down.
+					if (null == workItem)
+					{
+						// Double lock for quit.
+                        if (_workerThreads.Count > _stpStartInfo.MinWorkerThreads)
+						{
+							lock(_workerThreads.SyncRoot)
+							{
+                                if (_workerThreads.Count > _stpStartInfo.MinWorkerThreads)
+								{
+									// Inform that the thread is quiting and then quit.
+									// This method must be called within this lock or else
+									// more threads will quit and the thread pool will go
+									// below the lower limit.
+									InformCompleted();
+									break;
+								}
+							}
+						}
+					}
+
+					// If we didn't quit then skip to the next iteration.
+					if (null == workItem)
+					{
+						continue;
+					}
+
+					try 
+					{
+						// Initialize the value to false
+						bInUseWorkerThreadsWasIncremented = false;
+
+                        // Set the Current Work Item of the thread.
+                        // Store the Current Work Item  before the workItem.StartingWorkItem() is called, 
+                        // so WorkItem.Cancel can work when the work item is between InQueue and InProgress 
+                        // states.
+                        // If the work item has been cancelled BEFORE the workItem.StartingWorkItem() 
+                        // (work item is in InQueue state) then workItem.StartingWorkItem() will return false.
+                        // If the work item has been cancelled AFTER the workItem.StartingWorkItem() then
+                        // (work item is in InProgress state) then the thread will be aborted
+                        CurrentThreadEntry.CurrentWorkItem = workItem;
+
+						// Change the state of the work item to 'in progress' if possible.
+						// We do it here so if the work item has been canceled we won't 
+						// increment the _inUseWorkerThreads.
+						// The cancel mechanism doesn't delete items from the queue,  
+						// it marks the work item as canceled, and when the work item
+						// is dequeued, we just skip it.
+						// If the post execute of work item is set to always or to
+						// call when the work item is canceled then the StartingWorkItem()
+						// will return true, so the post execute can run.
+						if (!workItem.StartingWorkItem())
+						{
+							continue;
+						}
+
+						// Execute the callback.  Make sure to accurately
+						// record how many callbacks are currently executing.
+						int inUseWorkerThreads = Interlocked.Increment(ref _inUseWorkerThreads);
+						_windowsPCs.SampleThreads(_workerThreads.Count, inUseWorkerThreads);
+                        _localPCs.SampleThreads(_workerThreads.Count, inUseWorkerThreads);
+
+						// Mark that the _inUseWorkerThreads incremented, so in the finally{}
+						// statement we will decrement it correctly.
+						bInUseWorkerThreadsWasIncremented = true;
+
+                        workItem.FireWorkItemStarted();
+
+						ExecuteWorkItem(workItem);
+					}
+					catch(Exception ex)
+					{
+                        ex.GetHashCode();
+						// Do nothing
+					}
+					finally
+					{
+						workItem.DisposeOfState();
+
+						// Set the CurrentWorkItem to null, since we 
+						// no longer run user's code.
+                        CurrentThreadEntry.CurrentWorkItem = null;
+
+						// Decrement the _inUseWorkerThreads only if we had 
+						// incremented it. Note the cancelled work items don't
+						// increment _inUseWorkerThreads.
+						if (bInUseWorkerThreadsWasIncremented)
+						{
+							int inUseWorkerThreads = Interlocked.Decrement(ref _inUseWorkerThreads);
+							_windowsPCs.SampleThreads(_workerThreads.Count, inUseWorkerThreads);
+                            _localPCs.SampleThreads(_workerThreads.Count, inUseWorkerThreads);
+						}
+
+						// Notify that the work item has been completed.
+						// WorkItemsGroup may enqueue their next work item.
+						workItem.FireWorkItemCompleted();
+
+						// Decrement the number of work items here so the idle 
+						// ManualResetEvent won't fluctuate.
+						DecrementWorkItemsCount();
+					}
+				}
+			} 
+			catch(ThreadAbortException tae)
+			{
+                tae.GetHashCode();
+                // Handle the abort exception gracfully.
+#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
+				Thread.ResetAbort();
+#endif
+            }
+			catch(Exception e)
+			{
+				Debug.Assert(null != e);
+			}
+			finally
+			{
+				InformCompleted();
+                FireOnThreadTermination();
+			}
+		}
+
+		private void ExecuteWorkItem(WorkItem workItem)
+		{
+			_windowsPCs.SampleWorkItemsWaitTime(workItem.WaitingTime);
+            _localPCs.SampleWorkItemsWaitTime(workItem.WaitingTime);
+			try
+			{
+				workItem.Execute();
+			}
+			finally
+			{
+				_windowsPCs.SampleWorkItemsProcessTime(workItem.ProcessTime);
+                _localPCs.SampleWorkItemsProcessTime(workItem.ProcessTime);
+			}
+		}
+
+
+		#endregion
+
+		#region Public Methods
+
+		private void ValidateWaitForIdle()
+		{
+            if (null != CurrentThreadEntry && CurrentThreadEntry.AssociatedSmartThreadPool == this)
+			{
+				throw new NotSupportedException(
+					"WaitForIdle cannot be called from a thread on its SmartThreadPool, it causes a deadlock");
+			}
+		}
+
+		internal static void ValidateWorkItemsGroupWaitForIdle(IWorkItemsGroup workItemsGroup)
+		{
+            if (null == CurrentThreadEntry)
+            {
+                return;
+            }
+
+            WorkItem workItem = CurrentThreadEntry.CurrentWorkItem;
+            ValidateWorkItemsGroupWaitForIdleImpl(workItemsGroup, workItem);
+			if ((null != workItemsGroup) &&
+                (null != workItem) &&
+                CurrentThreadEntry.CurrentWorkItem.WasQueuedBy(workItemsGroup))
+			{
+				throw new NotSupportedException("WaitForIdle cannot be called from a thread on its SmartThreadPool, it causes a deadlock");
+			}
+		}
+
+		[MethodImpl(MethodImplOptions.NoInlining)]
+		private static void ValidateWorkItemsGroupWaitForIdleImpl(IWorkItemsGroup workItemsGroup, WorkItem workItem)
+		{
+			if ((null != workItemsGroup) && 
+				(null != workItem) &&
+				workItem.WasQueuedBy(workItemsGroup))
+			{
+				throw new NotSupportedException("WaitForIdle cannot be called from a thread on its SmartThreadPool, it causes a deadlock");
+			}
+		}
+
+		/// <summary>
+		/// Force the SmartThreadPool to shutdown
+		/// </summary>
+		public void Shutdown()
+		{
+			Shutdown(true, 0);
+		}
+
+        /// <summary>
+        /// Force the SmartThreadPool to shutdown with timeout
+        /// </summary>
+        public void Shutdown(bool forceAbort, TimeSpan timeout)
+		{
+			Shutdown(forceAbort, (int)timeout.TotalMilliseconds);
+		}
+
+		/// <summary>
+		/// Empties the queue of work items and abort the threads in the pool.
+		/// </summary>
+		public void Shutdown(bool forceAbort, int millisecondsTimeout)
+		{
+			ValidateNotDisposed();
+
+			ISTPInstancePerformanceCounters pcs = _windowsPCs;
+
+			if (NullSTPInstancePerformanceCounters.Instance != _windowsPCs)
+			{
+				// Set the _pcs to "null" to stop updating the performance
+				// counters
+				_windowsPCs = NullSTPInstancePerformanceCounters.Instance;
+
+                pcs.Dispose();
+			}
+
+			Thread [] threads;
+			lock(_workerThreads.SyncRoot)
+			{
+				// Shutdown the work items queue
+				_workItemsQueue.Dispose();
+
+				// Signal the threads to exit
+				_shutdown = true;
+				_shuttingDownEvent.Set();
+
+				// Make a copy of the threads' references in the pool
+				threads = new Thread [_workerThreads.Count];
+				_workerThreads.Keys.CopyTo(threads, 0);
+			}
+
+			int millisecondsLeft = millisecondsTimeout;
+            Stopwatch stopwatch = Stopwatch.StartNew();
+            //DateTime start = DateTime.UtcNow;
+			bool waitInfinitely = (Timeout.Infinite == millisecondsTimeout);
+			bool timeout = false;
+
+			// Each iteration we update the time left for the timeout.
+			foreach(Thread thread in threads)
+			{
+				// Join don't work with negative numbers
+				if (!waitInfinitely && (millisecondsLeft < 0))
+				{
+					timeout = true;
+					break;
+				}
+
+				// Wait for the thread to terminate
+				bool success = thread.Join(millisecondsLeft);
+				if(!success)
+				{
+					timeout = true;
+					break;
+				}
+
+				if(!waitInfinitely)
+				{
+					// Update the time left to wait
+                    //TimeSpan ts = DateTime.UtcNow - start;
+                    millisecondsLeft = millisecondsTimeout - (int)stopwatch.ElapsedMilliseconds;
+				}
+			}
+
+			if (timeout && forceAbort)
+			{
+				// Abort the threads in the pool
+				foreach(Thread thread in threads)
+				{
+                    
+					if ((thread != null)
+#if !(_WINDOWS_CE)
+                        && thread.IsAlive
+#endif                        
+                        )
+					{
+						try 
+						{
+                            thread.Abort(); // Shutdown
+						}
+						catch(SecurityException e)
+						{
+                            e.GetHashCode();
+						}
+						catch(ThreadStateException ex)
+						{
+                            ex.GetHashCode();
+							// In case the thread has been terminated 
+							// after the check if it is alive.
+						}
+					}
+				}
+			}
+		}
+
+		/// <summary>
+		/// Wait for all work items to complete
+		/// </summary>
+        /// <param name="waitableResults">Array of work item result objects</param>
+		/// <returns>
+		/// true when every work item in workItemResults has completed; otherwise false.
+		/// </returns>
+		public static bool WaitAll(
+			IWaitableResult [] waitableResults)
+		{
+            return WaitAll(waitableResults, Timeout.Infinite, true);
+		}
+
+		/// <summary>
+		/// Wait for all work items to complete
+		/// </summary>
+        /// <param name="waitableResults">Array of work item result objects</param>
+		/// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param>
+		/// <param name="exitContext">
+		/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 
+		/// </param>
+		/// <returns>
+		/// true when every work item in workItemResults has completed; otherwise false.
+		/// </returns>
+		public static bool WaitAll(
+			IWaitableResult [] waitableResults,
+			TimeSpan timeout,
+			bool exitContext)
+		{
+            return WaitAll(waitableResults, (int)timeout.TotalMilliseconds, exitContext);
+		}
+
+		/// <summary>
+		/// Wait for all work items to complete
+		/// </summary>
+        /// <param name="waitableResults">Array of work item result objects</param>
+		/// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param>
+		/// <param name="exitContext">
+		/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 
+		/// </param>
+		/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
+		/// <returns>
+		/// true when every work item in workItemResults has completed; otherwise false.
+		/// </returns>
+		public static bool WaitAll(
+            IWaitableResult[] waitableResults,  
+			TimeSpan timeout,
+			bool exitContext,
+			WaitHandle cancelWaitHandle)
+		{
+            return WaitAll(waitableResults, (int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle);
+		}
+
+		/// <summary>
+		/// Wait for all work items to complete
+		/// </summary>
+        /// <param name="waitableResults">Array of work item result objects</param>
+		/// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
+		/// <param name="exitContext">
+		/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 
+		/// </param>
+		/// <returns>
+		/// true when every work item in workItemResults has completed; otherwise false.
+		/// </returns>
+		public static bool WaitAll(
+			IWaitableResult [] waitableResults,  
+			int millisecondsTimeout,
+			bool exitContext)
+		{
+            return WorkItem.WaitAll(waitableResults, millisecondsTimeout, exitContext, null);
+		}
+
+		/// <summary>
+		/// Wait for all work items to complete
+		/// </summary>
+        /// <param name="waitableResults">Array of work item result objects</param>
+		/// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
+		/// <param name="exitContext">
+		/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 
+		/// </param>
+		/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
+		/// <returns>
+		/// true when every work item in workItemResults has completed; otherwise false.
+		/// </returns>
+		public static bool WaitAll(
+            IWaitableResult[] waitableResults,  
+			int millisecondsTimeout,
+			bool exitContext,
+			WaitHandle cancelWaitHandle)
+		{
+            return WorkItem.WaitAll(waitableResults, millisecondsTimeout, exitContext, cancelWaitHandle);
+		}
+
+
+		/// <summary>
+		/// Waits for any of the work items in the specified array to complete, cancel, or timeout
+		/// </summary>
+        /// <param name="waitableResults">Array of work item result objects</param>
+		/// <returns>
+		/// The array index of the work item result that satisfied the wait, or WaitTimeout if any of the work items has been canceled.
+		/// </returns>
+		public static int WaitAny(
+			IWaitableResult [] waitableResults)
+		{
+            return WaitAny(waitableResults, Timeout.Infinite, true);
+		}
+
+		/// <summary>
+		/// Waits for any of the work items in the specified array to complete, cancel, or timeout
+		/// </summary>
+        /// <param name="waitableResults">Array of work item result objects</param>
+		/// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param>
+		/// <param name="exitContext">
+		/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 
+		/// </param>
+		/// <returns>
+		/// 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.
+		/// </returns>
+		public static int WaitAny(
+            IWaitableResult[] waitableResults,
+			TimeSpan timeout,
+			bool exitContext)
+		{
+            return WaitAny(waitableResults, (int)timeout.TotalMilliseconds, exitContext);
+		}
+
+		/// <summary>
+		/// Waits for any of the work items in the specified array to complete, cancel, or timeout
+		/// </summary>
+        /// <param name="waitableResults">Array of work item result objects</param>
+		/// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param>
+		/// <param name="exitContext">
+		/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 
+		/// </param>
+		/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
+		/// <returns>
+		/// 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.
+		/// </returns>
+		public static int WaitAny(
+			IWaitableResult [] waitableResults,
+			TimeSpan timeout,
+			bool exitContext,
+			WaitHandle cancelWaitHandle)
+		{
+            return WaitAny(waitableResults, (int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle);
+		}
+
+		/// <summary>
+		/// Waits for any of the work items in the specified array to complete, cancel, or timeout
+		/// </summary>
+        /// <param name="waitableResults">Array of work item result objects</param>
+		/// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
+		/// <param name="exitContext">
+		/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 
+		/// </param>
+		/// <returns>
+		/// 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.
+		/// </returns>
+		public static int WaitAny(
+			IWaitableResult [] waitableResults,  
+			int millisecondsTimeout,
+			bool exitContext)
+		{
+            return WorkItem.WaitAny(waitableResults, millisecondsTimeout, exitContext, null);
+		}
+
+		/// <summary>
+		/// Waits for any of the work items in the specified array to complete, cancel, or timeout
+		/// </summary>
+        /// <param name="waitableResults">Array of work item result objects</param>
+		/// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
+		/// <param name="exitContext">
+		/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. 
+		/// </param>
+		/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
+		/// <returns>
+		/// 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.
+		/// </returns>
+		public static int WaitAny(
+			IWaitableResult [] waitableResults,  
+			int millisecondsTimeout,
+			bool exitContext,
+			WaitHandle cancelWaitHandle)
+		{
+            return WorkItem.WaitAny(waitableResults, millisecondsTimeout, exitContext, cancelWaitHandle);
+		}
+
+        /// <summary>
+        /// Creates a new WorkItemsGroup.
+        /// </summary>
+        /// <param name="concurrency">The number of work items that can be run concurrently</param>
+        /// <returns>A reference to the WorkItemsGroup</returns>
+		public IWorkItemsGroup CreateWorkItemsGroup(int concurrency)
+		{
+            IWorkItemsGroup workItemsGroup = new WorkItemsGroup(this, concurrency, _stpStartInfo);
+			return workItemsGroup;
+		}
+
+        /// <summary>
+        /// Creates a new WorkItemsGroup.
+        /// </summary>
+        /// <param name="concurrency">The number of work items that can be run concurrently</param>
+        /// <param name="wigStartInfo">A WorkItemsGroup configuration that overrides the default behavior</param>
+        /// <returns>A reference to the WorkItemsGroup</returns>
+		public IWorkItemsGroup CreateWorkItemsGroup(int concurrency, WIGStartInfo wigStartInfo)
+		{
+			IWorkItemsGroup workItemsGroup = new WorkItemsGroup(this, concurrency, wigStartInfo);
+			return workItemsGroup;
+		}
+
+        #region Fire Thread's Events
+
+        private void FireOnThreadInitialization()
+        {
+            if (null != _onThreadInitialization)
+            {
+                foreach (ThreadInitializationHandler tih in _onThreadInitialization.GetInvocationList())
+                {
+                    try
+                    {
+                        tih();
+                    }
+                    catch (Exception e)
+                    {
+                        e.GetHashCode();
+                        Debug.Assert(false);
+                        throw;
+                    }
+                }
+            }
+        }
+
+        private void FireOnThreadTermination()
+        {
+            if (null != _onThreadTermination)
+            {
+                foreach (ThreadTerminationHandler tth in _onThreadTermination.GetInvocationList())
+                {
+                    try
+                    {
+                        tth();
+                    }
+                    catch (Exception e)
+                    {
+                        e.GetHashCode();
+                        Debug.Assert(false);
+                        throw;
+                    }
+                }
+            }
+        }
+
+        #endregion
+
+        /// <summary>
+        /// This event is fired when a thread is created.
+        /// Use it to initialize a thread before the work items use it.
+        /// </summary>
+        public event ThreadInitializationHandler OnThreadInitialization
+        {
+            add { _onThreadInitialization += value; }
+            remove { _onThreadInitialization -= value; }
+        }
+
+        /// <summary>
+        /// This event is fired when a thread is terminating.
+        /// Use it for cleanup.
+        /// </summary>
+        public event ThreadTerminationHandler OnThreadTermination
+        {
+            add { _onThreadTermination += value; }
+            remove { _onThreadTermination -= value; }
+        }
+
+
+        internal void CancelAbortWorkItemsGroup(WorkItemsGroup wig)
+        {
+            foreach (ThreadEntry threadEntry in _workerThreads.Values)
+            {
+                WorkItem workItem = threadEntry.CurrentWorkItem;
+                if (null != workItem &&
+                    workItem.WasQueuedBy(wig) &&
+                    !workItem.IsCanceled)
+                {
+                    threadEntry.CurrentWorkItem.GetWorkItemResult().Cancel(true);
+                }
+            }
+        }
+
+        
+
+		#endregion
+
+		#region Properties
+
+		/// <summary>
+		/// Get/Set the lower limit of threads in the pool.
+		/// </summary>
+		public int MinThreads 
+		{ 
+			get 
+			{
+				ValidateNotDisposed();
+                return _stpStartInfo.MinWorkerThreads; 
+			}
+            set
+            {
+                Debug.Assert(value >= 0);
+                Debug.Assert(value <= _stpStartInfo.MaxWorkerThreads);
+                if (_stpStartInfo.MaxWorkerThreads < value)
+                {
+                    _stpStartInfo.MaxWorkerThreads = value;
+                }
+                _stpStartInfo.MinWorkerThreads = value;
+                StartOptimalNumberOfThreads();
+            }
+		}
+
+	    /// <summary>
+		/// Get/Set the upper limit of threads in the pool.
+		/// </summary>
+		public int MaxThreads 
+		{ 
+			get 
+			{
+				ValidateNotDisposed();
+                return _stpStartInfo.MaxWorkerThreads; 
+			} 
+
+			set 
+			{
+                Debug.Assert(value > 0);
+                Debug.Assert(value >= _stpStartInfo.MinWorkerThreads);
+                if (_stpStartInfo.MinWorkerThreads > value)
+                {
+                    _stpStartInfo.MinWorkerThreads = value;
+                }
+                _stpStartInfo.MaxWorkerThreads = value;
+                StartOptimalNumberOfThreads();
+            } 
+		}
+		/// <summary>
+		/// Get the number of threads in the thread pool.
+		/// Should be between the lower and the upper limits.
+		/// </summary>
+		public int ActiveThreads 
+		{ 
+			get 
+			{
+				ValidateNotDisposed();
+				return _workerThreads.Count; 
+			} 
+		}
+
+		/// <summary>
+		/// Get the number of busy (not idle) threads in the thread pool.
+		/// </summary>
+		public int InUseThreads 
+		{ 
+			get 
+			{ 
+				ValidateNotDisposed();
+				return _inUseWorkerThreads; 
+			} 
+		}
+
+        /// <summary>
+        /// Returns true if the current running work item has been cancelled.
+        /// Must be used within the work item's callback method.
+        /// The work item should sample this value in order to know if it
+        /// needs to quit before its completion.
+        /// </summary>
+        public static bool IsWorkItemCanceled
+        {
+            get
+            {
+                return CurrentThreadEntry.CurrentWorkItem.IsCanceled;
+            }
+        } 
+        
+        /// <summary>
+        /// Checks if the work item has been cancelled, and if yes then abort the thread.
+        /// Can be used with Cancel and timeout
+        /// </summary>
+        public static void AbortOnWorkItemCancel()
+        {
+            if (IsWorkItemCanceled)
+            {
+                Thread.CurrentThread.Abort();
+            }
+        }
+
+        /// <summary>
+        /// Thread Pool start information (readonly)
+        /// </summary>
+        public STPStartInfo STPStartInfo
+        {
+            get 
+            {
+                return _stpStartInfo.AsReadOnly(); 
+            }
+        }
+
+	    public bool IsShuttingdown
+	    {
+            get { return _shutdown;  }
+	    }
+
+        /// <summary>
+        /// Return the local calculated performance counters
+        /// Available only if STPStartInfo.EnableLocalPerformanceCounters is true.
+        /// </summary>
+        public ISTPPerformanceCountersReader PerformanceCountersReader
+        {
+            get { return (ISTPPerformanceCountersReader)_localPCs; }
+        }
+
+        #endregion
+
+        #region IDisposable Members
+
+        public void Dispose()
+        {
+            if (!_isDisposed)
+            {
+                if (!_shutdown)
+                {
+                    Shutdown();
+                }
+
+                if (null != _shuttingDownEvent)
+                {
+                    _shuttingDownEvent.Close();
+                    _shuttingDownEvent = null;
+                }
+                _workerThreads.Clear();
+                
+                if (null != _isIdleWaitHandle)
+                {
+                    _isIdleWaitHandle.Close();
+                    _isIdleWaitHandle = null;
+                }
+
+                _isDisposed = true;
+            }
+        }
+
+        private void ValidateNotDisposed()
+        {
+            if(_isDisposed)
+            {
+                throw new ObjectDisposedException(GetType().ToString(), "The SmartThreadPool has been shutdown");
+            }
+        }
+        #endregion
+
+        #region WorkItemsGroupBase Overrides
+
+        /// <summary>
+        /// Get/Set the maximum number of work items that execute cocurrency on the thread pool
+        /// </summary>
+        public override int Concurrency
+	    {
+	        get { return MaxThreads; }
+	        set { MaxThreads = value; }
+	    }
+
+	    /// <summary>
+	    /// Get the number of work items in the queue.
+	    /// </summary>
+	    public override int WaitingCallbacks
+	    {
+	        get
+	        {
+	            ValidateNotDisposed();
+	            return _workItemsQueue.Count;
+	        }
+	    }
+
+        /// <summary>
+        /// Get an array with all the state objects of the currently running items.
+        /// The array represents a snap shot and impact performance.
+        /// </summary>
+        public override object[] GetStates()
+        {
+            object[] states = _workItemsQueue.GetStates();
+            return states;
+        }
+
+        /// <summary>
+        /// WorkItemsGroup start information (readonly)
+        /// </summary>
+        public override WIGStartInfo WIGStartInfo
+        {
+            get { return _stpStartInfo.AsReadOnly(); }
+        }
+
+	    /// <summary>
+        /// Start the thread pool if it was started suspended.
+        /// If it is already running, this method is ignored.
+        /// </summary>
+        public override void Start()
+        {
+            if (!_isSuspended)
+            {
+                return;
+            }
+            _isSuspended = false;
+
+            ICollection workItemsGroups = _workItemsGroups.Values;
+            foreach (WorkItemsGroup workItemsGroup in workItemsGroups)
+            {
+                workItemsGroup.OnSTPIsStarting();
+            }
+
+            StartOptimalNumberOfThreads();
+        }
+
+        /// <summary>
+        /// Cancel all work items using thread abortion
+        /// </summary>
+        /// <param name="abortExecution">True to stop work items by raising ThreadAbortException</param>
+        public override void Cancel(bool abortExecution)
+        {
+            _canceledSmartThreadPool.IsCanceled = true;
+            _canceledSmartThreadPool = new CanceledWorkItemsGroup();
+
+            ICollection workItemsGroups = _workItemsGroups.Values;
+            foreach (WorkItemsGroup workItemsGroup in workItemsGroups)
+            {
+                workItemsGroup.Cancel(abortExecution);
+            }
+
+            if (abortExecution)
+            {
+                foreach (ThreadEntry threadEntry in _workerThreads.Values)
+                {
+                    WorkItem workItem = threadEntry.CurrentWorkItem;
+                    if (null != workItem &&
+                        threadEntry.AssociatedSmartThreadPool == this &&
+                        !workItem.IsCanceled)
+                    {
+                        threadEntry.CurrentWorkItem.GetWorkItemResult().Cancel(true);
+                    }
+                }
+            }
+        }
+
+	    /// <summary>
+        /// Wait for the thread pool to be idle
+        /// </summary>
+        public override bool WaitForIdle(int millisecondsTimeout)
+        {
+            ValidateWaitForIdle();
+            return STPEventWaitHandle.WaitOne(_isIdleWaitHandle, millisecondsTimeout, false);
+        }
+
+        /// <summary>
+        /// This event is fired when all work items are completed.
+        /// (When IsIdle changes to true)
+        /// This event only work on WorkItemsGroup. On SmartThreadPool
+        /// it throws the NotImplementedException.
+        /// </summary>
+        public override event WorkItemsGroupIdleHandler OnIdle
+        {
+            add
+            {
+                throw new NotImplementedException("This event is not implemented in the SmartThreadPool class. Please create a WorkItemsGroup in order to use this feature.");
+                //_onIdle += value;
+            }
+            remove
+            {
+                throw new NotImplementedException("This event is not implemented in the SmartThreadPool class. Please create a WorkItemsGroup in order to use this feature.");
+                //_onIdle -= value;
+            }
+        }
+
+	    internal override void PreQueueWorkItem()
+        {
+            ValidateNotDisposed();   
+        }
+
+        #endregion
+
+        #region Join, Choice, Pipe, etc.
+
+        /// <summary>
+        /// Executes all actions in parallel.
+        /// Returns when they all finish.
+        /// </summary>
+        /// <param name="actions">Actions to execute</param>
+        public void Join(IEnumerable<Action> actions)
+        {
+            WIGStartInfo wigStartInfo = new WIGStartInfo { StartSuspended = true };
+            IWorkItemsGroup workItemsGroup = CreateWorkItemsGroup(int.MaxValue, wigStartInfo);
+            foreach (Action action in actions)
+            {
+                workItemsGroup.QueueWorkItem(action);
+            }
+            workItemsGroup.Start();
+            workItemsGroup.WaitForIdle();
+        }
+
+        /// <summary>
+        /// Executes all actions in parallel.
+        /// Returns when they all finish.
+        /// </summary>
+        /// <param name="actions">Actions to execute</param>
+        public void Join(params Action[] actions)
+        {
+            Join((IEnumerable<Action>)actions);
+        }
+
+        private class ChoiceIndex
+        {
+            public int _index = -1;
+        }
+
+        /// <summary>
+        /// Executes all actions in parallel
+        /// Returns when the first one completes
+        /// </summary>
+        /// <param name="actions">Actions to execute</param>
+        public int Choice(IEnumerable<Action> actions)
+        {
+            WIGStartInfo wigStartInfo = new WIGStartInfo { StartSuspended = true };
+            IWorkItemsGroup workItemsGroup = CreateWorkItemsGroup(int.MaxValue, wigStartInfo);
+
+            ManualResetEvent anActionCompleted = new ManualResetEvent(false);
+
+            ChoiceIndex choiceIndex = new ChoiceIndex();
+            
+            int i = 0;
+            foreach (Action action in actions)
+            {
+                Action act = action;
+                int value = i;
+                workItemsGroup.QueueWorkItem(() => { act(); Interlocked.CompareExchange(ref choiceIndex._index, value, -1); anActionCompleted.Set(); });
+                ++i;
+            }
+	        workItemsGroup.Start();
+            anActionCompleted.WaitOne();
+
+            return choiceIndex._index;
+        }
+
+        /// <summary>
+        /// Executes all actions in parallel
+        /// Returns when the first one completes
+        /// </summary>
+        /// <param name="actions">Actions to execute</param>
+        public int Choice(params Action[] actions)
+	    {
+            return Choice((IEnumerable<Action>)actions);
+        }
+
+        /// <summary>
+        /// Executes actions in sequence asynchronously.
+        /// Returns immediately.
+        /// </summary>
+        /// <param name="pipeState">A state context that passes </param>
+        /// <param name="actions">Actions to execute in the order they should run</param>
+        public void Pipe<T>(T pipeState, IEnumerable<Action<T>> actions)
+        {
+            WIGStartInfo wigStartInfo = new WIGStartInfo { StartSuspended = true };
+            IWorkItemsGroup workItemsGroup = CreateWorkItemsGroup(1, wigStartInfo);
+            foreach (Action<T> action in actions)
+            {
+                Action<T> act = action;
+                workItemsGroup.QueueWorkItem(() => act(pipeState));
+            }
+            workItemsGroup.Start();
+            workItemsGroup.WaitForIdle();
+        }
+
+        /// <summary>
+        /// Executes actions in sequence asynchronously.
+        /// Returns immediately.
+        /// </summary>
+        /// <param name="pipeState"></param>
+        /// <param name="actions">Actions to execute in the order they should run</param>
+        public void Pipe<T>(T pipeState, params Action<T>[] actions)
+        {
+            Pipe(pipeState, (IEnumerable<Action<T>>)actions);
+        }
+        #endregion
+	}
+	#endregion
+}

+ 89 - 89
ThirdParty/SmartThreadPool/SynchronizedDictionary.cs

@@ -1,89 +1,89 @@
-using System.Collections.Generic;
-
-namespace Amib.Threading.Internal
-{
-    internal class SynchronizedDictionary<TKey, TValue>
-    {
-        private readonly Dictionary<TKey, TValue> _dictionary;
-        private readonly object _lock;
-
-        public SynchronizedDictionary()
-        {
-            _lock = new object();
-            _dictionary = new Dictionary<TKey, TValue>();
-        }
-
-        public int Count
-        {
-            get { return _dictionary.Count; }
-        }
-
-        public bool Contains(TKey key)
-        {
-            lock (_lock)
-            {
-                return _dictionary.ContainsKey(key);
-            }
-        }
-
-        public void Remove(TKey key)
-        {
-            lock (_lock)
-            {
-                _dictionary.Remove(key);
-            }
-        }
-
-        public object SyncRoot
-        {
-            get { return _lock; }
-        }
-
-        public TValue this[TKey key]
-        {
-            get
-            {
-                lock (_lock)
-                {
-                    return _dictionary[key];
-                }
-            }
-            set
-            {
-                lock (_lock)
-                {
-                    _dictionary[key] = value;
-                }
-            }
-        }
-
-        public Dictionary<TKey, TValue>.KeyCollection Keys
-        {
-            get
-            {
-                lock (_lock)
-                {
-                    return _dictionary.Keys;
-                }
-            }
-        }
-
-        public Dictionary<TKey, TValue>.ValueCollection Values
-        {
-            get
-            {
-                lock (_lock)
-                {
-                    return _dictionary.Values;
-                }
-            }
-        }
-        public void Clear()
-        {
-            lock (_lock)
-            {
-                _dictionary.Clear();
-            }
-        }
-    }
-}
+using System.Collections.Generic;
+
+namespace Amib.Threading.Internal
+{
+    internal class SynchronizedDictionary<TKey, TValue>
+    {
+        private readonly Dictionary<TKey, TValue> _dictionary;
+        private readonly object _lock;
+
+        public SynchronizedDictionary()
+        {
+            _lock = new object();
+            _dictionary = new Dictionary<TKey, TValue>();
+        }
+
+        public int Count
+        {
+            get { return _dictionary.Count; }
+        }
+
+        public bool Contains(TKey key)
+        {
+            lock (_lock)
+            {
+                return _dictionary.ContainsKey(key);
+            }
+        }
+
+        public void Remove(TKey key)
+        {
+            lock (_lock)
+            {
+                _dictionary.Remove(key);
+            }
+        }
+
+        public object SyncRoot
+        {
+            get { return _lock; }
+        }
+
+        public TValue this[TKey key]
+        {
+            get
+            {
+                lock (_lock)
+                {
+                    return _dictionary[key];
+                }
+            }
+            set
+            {
+                lock (_lock)
+                {
+                    _dictionary[key] = value;
+                }
+            }
+        }
+
+        public Dictionary<TKey, TValue>.KeyCollection Keys
+        {
+            get
+            {
+                lock (_lock)
+                {
+                    return _dictionary.Keys;
+                }
+            }
+        }
+
+        public Dictionary<TKey, TValue>.ValueCollection Values
+        {
+            get
+            {
+                lock (_lock)
+                {
+                    return _dictionary.Values;
+                }
+            }
+        }
+        public void Clear()
+        {
+            lock (_lock)
+            {
+                _dictionary.Clear();
+            }
+        }
+    }
+}

+ 171 - 171
ThirdParty/SmartThreadPool/WIGStartInfo.cs

@@ -1,171 +1,171 @@
-using System;
-
-namespace Amib.Threading
-{
-	/// <summary>
-	/// Summary description for WIGStartInfo.
-	/// </summary>
-	public class WIGStartInfo
-	{
-        private bool _useCallerCallContext;
-        private bool _useCallerHttpContext;
-        private bool _disposeOfStateObjects;
-        private CallToPostExecute _callToPostExecute;
-        private PostExecuteWorkItemCallback _postExecuteWorkItemCallback;
-        private bool _startSuspended;
-        private WorkItemPriority _workItemPriority;
-        private bool _fillStateWithArgs;
-
-        protected bool _readOnly;
-
-	    public WIGStartInfo()
-        {
-	        _fillStateWithArgs = SmartThreadPool.DefaultFillStateWithArgs;
-	        _workItemPriority = SmartThreadPool.DefaultWorkItemPriority;
-            _startSuspended = SmartThreadPool.DefaultStartSuspended;
-            _postExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback;
-            _callToPostExecute = SmartThreadPool.DefaultCallToPostExecute;
-            _disposeOfStateObjects = SmartThreadPool.DefaultDisposeOfStateObjects;
-            _useCallerHttpContext = SmartThreadPool.DefaultUseCallerHttpContext;
-            _useCallerCallContext = SmartThreadPool.DefaultUseCallerCallContext;
-        }
-
-	    public WIGStartInfo(WIGStartInfo wigStartInfo)
-        {
-            _useCallerCallContext = wigStartInfo.UseCallerCallContext;
-            _useCallerHttpContext = wigStartInfo.UseCallerHttpContext;
-            _disposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
-            _callToPostExecute = wigStartInfo.CallToPostExecute;
-            _postExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback;
-            _workItemPriority = wigStartInfo.WorkItemPriority;
-            _startSuspended = wigStartInfo.StartSuspended;
-            _fillStateWithArgs = wigStartInfo.FillStateWithArgs;
-        }
-
-        protected void ThrowIfReadOnly()
-        {
-            if (_readOnly)
-            {
-                throw new NotSupportedException("This is a readonly instance and set is not supported");
-            }
-        }
-
-	    /// <summary>
-	    /// Get/Set if to use the caller's security context
-	    /// </summary>
-	    public virtual bool UseCallerCallContext
-	    {
-	        get { return _useCallerCallContext; }
-            set 
-            { 
-                ThrowIfReadOnly();  
-                _useCallerCallContext = value; 
-            }
-	    }
-
-
-	    /// <summary>
-	    /// Get/Set if to use the caller's HTTP context
-	    /// </summary>
-	    public virtual bool UseCallerHttpContext
-	    {
-	        get { return _useCallerHttpContext; }
-            set 
-            { 
-                ThrowIfReadOnly();  
-                _useCallerHttpContext = value; 
-            }
-	    }
-
-
-	    /// <summary>
-	    /// Get/Set if to dispose of the state object of a work item
-	    /// </summary>
-	    public virtual bool DisposeOfStateObjects
-	    {
-	        get { return _disposeOfStateObjects; }
-            set 
-            { 
-                ThrowIfReadOnly();  
-                _disposeOfStateObjects = value; 
-            }
-	    }
-
-
-	    /// <summary>
-	    /// Get/Set the run the post execute options
-	    /// </summary>
-	    public virtual CallToPostExecute CallToPostExecute
-	    {
-	        get { return _callToPostExecute; }
-            set 
-            { 
-                ThrowIfReadOnly();  
-                _callToPostExecute = value; 
-            }
-	    }
-
-
-	    /// <summary>
-	    /// Get/Set the default post execute callback
-	    /// </summary>
-	    public virtual PostExecuteWorkItemCallback PostExecuteWorkItemCallback
-	    {
-	        get { return _postExecuteWorkItemCallback; }
-            set 
-            { 
-                ThrowIfReadOnly();  
-                _postExecuteWorkItemCallback = value; 
-            }
-	    }
-
-
-	    /// <summary>
-	    /// Get/Set if the work items execution should be suspended until the Start()
-	    /// method is called.
-	    /// </summary>
-	    public virtual bool StartSuspended
-	    {
-	        get { return _startSuspended; }
-            set 
-            { 
-                ThrowIfReadOnly();  
-                _startSuspended = value; 
-            }
-	    }
-
-
-	    /// <summary>
-	    /// Get/Set the default priority that a work item gets when it is enqueued
-	    /// </summary>
-	    public virtual WorkItemPriority WorkItemPriority
-	    {
-	        get { return _workItemPriority; }
-	        set { _workItemPriority = value; }
-	    }
-
-	    /// <summary>
-        /// Get/Set the if QueueWorkItem of Action&lt;...&gt;/Func&lt;...&gt; fill the
-	    /// arguments as an object array into the state of the work item.
-	    /// The arguments can be access later by IWorkItemResult.State.
-	    /// </summary>
-	    public virtual bool FillStateWithArgs
-	    {
-	        get { return _fillStateWithArgs; }
-            set 
-            { 
-                ThrowIfReadOnly();  
-                _fillStateWithArgs = value; 
-            }
-	    }
-
-	    /// <summary>
-        /// Get a readonly version of this WIGStartInfo
-        /// </summary>
-        /// <returns>Returns a readonly reference to this WIGStartInfoRO</returns>
-        public WIGStartInfo AsReadOnly()
-	    {
-            return new WIGStartInfo(this) { _readOnly = true };
-	    }
-    }
-}
+using System;
+
+namespace Amib.Threading
+{
+	/// <summary>
+	/// Summary description for WIGStartInfo.
+	/// </summary>
+	public class WIGStartInfo
+	{
+        private bool _useCallerCallContext;
+        private bool _useCallerHttpContext;
+        private bool _disposeOfStateObjects;
+        private CallToPostExecute _callToPostExecute;
+        private PostExecuteWorkItemCallback _postExecuteWorkItemCallback;
+        private bool _startSuspended;
+        private WorkItemPriority _workItemPriority;
+        private bool _fillStateWithArgs;
+
+        protected bool _readOnly;
+
+	    public WIGStartInfo()
+        {
+	        _fillStateWithArgs = SmartThreadPool.DefaultFillStateWithArgs;
+	        _workItemPriority = SmartThreadPool.DefaultWorkItemPriority;
+            _startSuspended = SmartThreadPool.DefaultStartSuspended;
+            _postExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback;
+            _callToPostExecute = SmartThreadPool.DefaultCallToPostExecute;
+            _disposeOfStateObjects = SmartThreadPool.DefaultDisposeOfStateObjects;
+            _useCallerHttpContext = SmartThreadPool.DefaultUseCallerHttpContext;
+            _useCallerCallContext = SmartThreadPool.DefaultUseCallerCallContext;
+        }
+
+	    public WIGStartInfo(WIGStartInfo wigStartInfo)
+        {
+            _useCallerCallContext = wigStartInfo.UseCallerCallContext;
+            _useCallerHttpContext = wigStartInfo.UseCallerHttpContext;
+            _disposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
+            _callToPostExecute = wigStartInfo.CallToPostExecute;
+            _postExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback;
+            _workItemPriority = wigStartInfo.WorkItemPriority;
+            _startSuspended = wigStartInfo.StartSuspended;
+            _fillStateWithArgs = wigStartInfo.FillStateWithArgs;
+        }
+
+        protected void ThrowIfReadOnly()
+        {
+            if (_readOnly)
+            {
+                throw new NotSupportedException("This is a readonly instance and set is not supported");
+            }
+        }
+
+	    /// <summary>
+	    /// Get/Set if to use the caller's security context
+	    /// </summary>
+	    public virtual bool UseCallerCallContext
+	    {
+	        get { return _useCallerCallContext; }
+            set 
+            { 
+                ThrowIfReadOnly();  
+                _useCallerCallContext = value; 
+            }
+	    }
+
+
+	    /// <summary>
+	    /// Get/Set if to use the caller's HTTP context
+	    /// </summary>
+	    public virtual bool UseCallerHttpContext
+	    {
+	        get { return _useCallerHttpContext; }
+            set 
+            { 
+                ThrowIfReadOnly();  
+                _useCallerHttpContext = value; 
+            }
+	    }
+
+
+	    /// <summary>
+	    /// Get/Set if to dispose of the state object of a work item
+	    /// </summary>
+	    public virtual bool DisposeOfStateObjects
+	    {
+	        get { return _disposeOfStateObjects; }
+            set 
+            { 
+                ThrowIfReadOnly();  
+                _disposeOfStateObjects = value; 
+            }
+	    }
+
+
+	    /// <summary>
+	    /// Get/Set the run the post execute options
+	    /// </summary>
+	    public virtual CallToPostExecute CallToPostExecute
+	    {
+	        get { return _callToPostExecute; }
+            set 
+            { 
+                ThrowIfReadOnly();  
+                _callToPostExecute = value; 
+            }
+	    }
+
+
+	    /// <summary>
+	    /// Get/Set the default post execute callback
+	    /// </summary>
+	    public virtual PostExecuteWorkItemCallback PostExecuteWorkItemCallback
+	    {
+	        get { return _postExecuteWorkItemCallback; }
+            set 
+            { 
+                ThrowIfReadOnly();  
+                _postExecuteWorkItemCallback = value; 
+            }
+	    }
+
+
+	    /// <summary>
+	    /// Get/Set if the work items execution should be suspended until the Start()
+	    /// method is called.
+	    /// </summary>
+	    public virtual bool StartSuspended
+	    {
+	        get { return _startSuspended; }
+            set 
+            { 
+                ThrowIfReadOnly();  
+                _startSuspended = value; 
+            }
+	    }
+
+
+	    /// <summary>
+	    /// Get/Set the default priority that a work item gets when it is enqueued
+	    /// </summary>
+	    public virtual WorkItemPriority WorkItemPriority
+	    {
+	        get { return _workItemPriority; }
+	        set { _workItemPriority = value; }
+	    }
+
+	    /// <summary>
+        /// Get/Set the if QueueWorkItem of Action&lt;...&gt;/Func&lt;...&gt; fill the
+	    /// arguments as an object array into the state of the work item.
+	    /// The arguments can be access later by IWorkItemResult.State.
+	    /// </summary>
+	    public virtual bool FillStateWithArgs
+	    {
+	        get { return _fillStateWithArgs; }
+            set 
+            { 
+                ThrowIfReadOnly();  
+                _fillStateWithArgs = value; 
+            }
+	    }
+
+	    /// <summary>
+        /// Get a readonly version of this WIGStartInfo
+        /// </summary>
+        /// <returns>Returns a readonly reference to this WIGStartInfoRO</returns>
+        public WIGStartInfo AsReadOnly()
+	    {
+            return new WIGStartInfo(this) { _readOnly = true };
+	    }
+    }
+}

+ 190 - 190
ThirdParty/SmartThreadPool/WorkItem.WorkItemResult.cs

@@ -1,190 +1,190 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading;
-
-namespace Amib.Threading.Internal
-{
-    public partial class WorkItem
-    {
-        #region WorkItemResult class
-
-        private class WorkItemResult : IWorkItemResult, IInternalWorkItemResult, IInternalWaitableResult
-        {
-            /// <summary>
-            /// A back reference to the work item
-            /// </summary>
-            private readonly WorkItem _workItem;
-
-            public WorkItemResult(WorkItem workItem)
-            {
-                _workItem = workItem;
-            }
-
-            internal WorkItem GetWorkItem()
-            {
-                return _workItem;
-            }
-
-            #region IWorkItemResult Members
-
-            public bool IsCompleted
-            {
-                get
-                {
-                    return _workItem.IsCompleted;
-                }
-            }
-
-            public bool IsCanceled
-            {
-                get
-                {
-                    return _workItem.IsCanceled;
-                }
-            }
-
-            public object GetResult()
-            {
-                return _workItem.GetResult(Timeout.Infinite, true, null);
-            }
-
-            public object GetResult(int millisecondsTimeout, bool exitContext)
-            {
-                return _workItem.GetResult(millisecondsTimeout, exitContext, null);
-            }
-
-            public object GetResult(TimeSpan timeout, bool exitContext)
-            {
-                return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null);
-            }
-
-            public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle)
-            {
-                return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle);
-            }
-
-            public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle)
-            {
-                return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle);
-            }
-
-            public object GetResult(out Exception e)
-            {
-                return _workItem.GetResult(Timeout.Infinite, true, null, out e);
-            }
-
-            public object GetResult(int millisecondsTimeout, bool exitContext, out Exception e)
-            {
-                return _workItem.GetResult(millisecondsTimeout, exitContext, null, out e);
-            }
-
-            public object GetResult(TimeSpan timeout, bool exitContext, out Exception e)
-            {
-                return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null, out e);
-            }
-
-            public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
-            {
-                return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e);
-            }
-
-            public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
-            {
-                return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle, out e);
-            }
-
-            public bool Cancel()
-            {
-                return Cancel(false);
-            }
-
-            public bool Cancel(bool abortExecution)
-            {
-                return _workItem.Cancel(abortExecution);
-            }
-
-            public object State
-            {
-                get
-                {
-                    return _workItem._state;
-                }
-            }
-
-            public WorkItemPriority WorkItemPriority
-            {
-                get
-                {
-                    return _workItem._workItemInfo.WorkItemPriority;
-                }
-            }
-
-            /// <summary>
-            /// Return the result, same as GetResult()
-            /// </summary>
-            public object Result
-            {
-                get { return GetResult(); }
-            }
-
-            /// <summary>
-            /// Returns the exception if occured otherwise returns null.
-            /// This value is valid only after the work item completed,
-            /// before that it is always null.
-            /// </summary>
-            public object Exception
-            {
-                get { return _workItem._exception; }
-            }
-
-            #endregion
-
-            #region IInternalWorkItemResult Members
-
-            public event WorkItemStateCallback OnWorkItemStarted
-            {
-                add
-                {
-                    _workItem.OnWorkItemStarted += value;
-                }
-                remove
-                {
-                    _workItem.OnWorkItemStarted -= value;
-                }
-            }
-
-
-            public event WorkItemStateCallback OnWorkItemCompleted
-            {
-                add
-                {
-                    _workItem.OnWorkItemCompleted += value;
-                }
-                remove
-                {
-                    _workItem.OnWorkItemCompleted -= value;
-                }
-            }
-
-            #endregion
-
-            #region IInternalWorkItemResult Members
-
-            public IWorkItemResult GetWorkItemResult()
-            {
-                return this;
-            }
-
-            public IWorkItemResult<TResult> GetWorkItemResultT<TResult>()
-            {
-                return new WorkItemResultTWrapper<TResult>(this);
-            }
-
-            #endregion
-        }
-
-        #endregion
-
-    }
-}
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading;
+
+namespace Amib.Threading.Internal
+{
+    public partial class WorkItem
+    {
+        #region WorkItemResult class
+
+        private class WorkItemResult : IWorkItemResult, IInternalWorkItemResult, IInternalWaitableResult
+        {
+            /// <summary>
+            /// A back reference to the work item
+            /// </summary>
+            private readonly WorkItem _workItem;
+
+            public WorkItemResult(WorkItem workItem)
+            {
+                _workItem = workItem;
+            }
+
+            internal WorkItem GetWorkItem()
+            {
+                return _workItem;
+            }
+
+            #region IWorkItemResult Members
+
+            public bool IsCompleted
+            {
+                get
+                {
+                    return _workItem.IsCompleted;
+                }
+            }
+
+            public bool IsCanceled
+            {
+                get
+                {
+                    return _workItem.IsCanceled;
+                }
+            }
+
+            public object GetResult()
+            {
+                return _workItem.GetResult(Timeout.Infinite, true, null);
+            }
+
+            public object GetResult(int millisecondsTimeout, bool exitContext)
+            {
+                return _workItem.GetResult(millisecondsTimeout, exitContext, null);
+            }
+
+            public object GetResult(TimeSpan timeout, bool exitContext)
+            {
+                return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null);
+            }
+
+            public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle)
+            {
+                return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle);
+            }
+
+            public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle)
+            {
+                return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle);
+            }
+
+            public object GetResult(out Exception e)
+            {
+                return _workItem.GetResult(Timeout.Infinite, true, null, out e);
+            }
+
+            public object GetResult(int millisecondsTimeout, bool exitContext, out Exception e)
+            {
+                return _workItem.GetResult(millisecondsTimeout, exitContext, null, out e);
+            }
+
+            public object GetResult(TimeSpan timeout, bool exitContext, out Exception e)
+            {
+                return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null, out e);
+            }
+
+            public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
+            {
+                return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e);
+            }
+
+            public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
+            {
+                return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle, out e);
+            }
+
+            public bool Cancel()
+            {
+                return Cancel(false);
+            }
+
+            public bool Cancel(bool abortExecution)
+            {
+                return _workItem.Cancel(abortExecution);
+            }
+
+            public object State
+            {
+                get
+                {
+                    return _workItem._state;
+                }
+            }
+
+            public WorkItemPriority WorkItemPriority
+            {
+                get
+                {
+                    return _workItem._workItemInfo.WorkItemPriority;
+                }
+            }
+
+            /// <summary>
+            /// Return the result, same as GetResult()
+            /// </summary>
+            public object Result
+            {
+                get { return GetResult(); }
+            }
+
+            /// <summary>
+            /// Returns the exception if occured otherwise returns null.
+            /// This value is valid only after the work item completed,
+            /// before that it is always null.
+            /// </summary>
+            public object Exception
+            {
+                get { return _workItem._exception; }
+            }
+
+            #endregion
+
+            #region IInternalWorkItemResult Members
+
+            public event WorkItemStateCallback OnWorkItemStarted
+            {
+                add
+                {
+                    _workItem.OnWorkItemStarted += value;
+                }
+                remove
+                {
+                    _workItem.OnWorkItemStarted -= value;
+                }
+            }
+
+
+            public event WorkItemStateCallback OnWorkItemCompleted
+            {
+                add
+                {
+                    _workItem.OnWorkItemCompleted += value;
+                }
+                remove
+                {
+                    _workItem.OnWorkItemCompleted -= value;
+                }
+            }
+
+            #endregion
+
+            #region IInternalWorkItemResult Members
+
+            public IWorkItemResult GetWorkItemResult()
+            {
+                return this;
+            }
+
+            public IWorkItemResult<TResult> GetWorkItemResultT<TResult>()
+            {
+                return new WorkItemResultTWrapper<TResult>(this);
+            }
+
+            #endregion
+        }
+
+        #endregion
+
+    }
+}

+ 343 - 343
ThirdParty/SmartThreadPool/WorkItemFactory.cs

@@ -1,343 +1,343 @@
-using System;
-
-namespace Amib.Threading.Internal
-{
-	#region WorkItemFactory class 
-
-	public class WorkItemFactory
-	{
-		/// <summary>
-		/// Create a new work item
-		/// </summary>
-		/// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
-		/// <param name="wigStartInfo">Work item group start information</param>
-		/// <param name="callback">A callback to execute</param>
-		/// <returns>Returns a work item</returns>
-		public static WorkItem CreateWorkItem(
-			IWorkItemsGroup workItemsGroup,
-			WIGStartInfo wigStartInfo,
-			WorkItemCallback callback)
-		{
-			return CreateWorkItem(workItemsGroup, wigStartInfo, callback, null);
-		}
-
-		/// <summary>
-		/// Create a new work item
-		/// </summary>
-        /// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
-        /// <param name="wigStartInfo">Work item group start information</param>
-		/// <param name="callback">A callback to execute</param>
-		/// <param name="workItemPriority">The priority of the work item</param>
-		/// <returns>Returns a work item</returns>
-		public static WorkItem CreateWorkItem(
-			IWorkItemsGroup workItemsGroup,
-			WIGStartInfo wigStartInfo,
-			WorkItemCallback callback, 
-			WorkItemPriority workItemPriority)
-		{
-			return CreateWorkItem(workItemsGroup, wigStartInfo, callback, null, workItemPriority);
-		}
-
-		/// <summary>
-		/// Create a new work item
-		/// </summary>
-        /// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
-        /// <param name="wigStartInfo">Work item group start information</param>
-		/// <param name="workItemInfo">Work item info</param>
-		/// <param name="callback">A callback to execute</param>
-		/// <returns>Returns a work item</returns>
-		public static WorkItem CreateWorkItem(
-			IWorkItemsGroup workItemsGroup,
-			WIGStartInfo wigStartInfo,
-			WorkItemInfo workItemInfo, 
-			WorkItemCallback callback)
-		{
-			return CreateWorkItem(
-				workItemsGroup,
-				wigStartInfo,
-				workItemInfo, 
-				callback, 
-				null);
-		}
-
-		/// <summary>
-		/// Create a new work item
-		/// </summary>
-        /// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
-        /// <param name="wigStartInfo">Work item group start information</param>
-		/// <param name="callback">A callback to execute</param>
-		/// <param name="state">
-		/// The context object of the work item. Used for passing arguments to the work item. 
-		/// </param>
-		/// <returns>Returns a work item</returns>
-		public static WorkItem CreateWorkItem(
-			IWorkItemsGroup workItemsGroup,
-			WIGStartInfo wigStartInfo,
-			WorkItemCallback callback, 
-			object state)
-		{
-			ValidateCallback(callback);
-            
-			WorkItemInfo workItemInfo = new WorkItemInfo();
-			workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
-			workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
-			workItemInfo.PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback;
-			workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
-			workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
-            workItemInfo.WorkItemPriority = wigStartInfo.WorkItemPriority;
-
-			WorkItem workItem = new WorkItem(
-				workItemsGroup,
-				workItemInfo,
-				callback, 
-				state);
-			return workItem;
-		}
-
-		/// <summary>
-		/// Create a new work item
-		/// </summary>
-		/// <param name="workItemsGroup">The work items group</param>
-		/// <param name="wigStartInfo">Work item group start information</param>
-		/// <param name="callback">A callback to execute</param>
-		/// <param name="state">
-		/// The context object of the work item. Used for passing arguments to the work item. 
-		/// </param>
-		/// <param name="workItemPriority">The work item priority</param>
-		/// <returns>Returns a work item</returns>
-		public static WorkItem CreateWorkItem(
-			IWorkItemsGroup workItemsGroup,
-			WIGStartInfo wigStartInfo,
-			WorkItemCallback callback, 
-			object state, 
-			WorkItemPriority workItemPriority)
-		{
-			ValidateCallback(callback);
-
-			WorkItemInfo workItemInfo = new WorkItemInfo();
-			workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
-			workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
-			workItemInfo.PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback;
-			workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
-			workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
-			workItemInfo.WorkItemPriority = workItemPriority;
-
-			WorkItem workItem = new WorkItem(
-				workItemsGroup,
-				workItemInfo,
-				callback, 
-				state);
-
-			return workItem;
-		}
-
-		/// <summary>
-		/// Create a new work item
-		/// </summary>
-        /// <param name="workItemsGroup">The work items group</param>
-		/// <param name="wigStartInfo">Work item group start information</param>
-		/// <param name="workItemInfo">Work item information</param>
-		/// <param name="callback">A callback to execute</param>
-		/// <param name="state">
-		/// The context object of the work item. Used for passing arguments to the work item. 
-		/// </param>
-		/// <returns>Returns a work item</returns>
-        public static WorkItem CreateWorkItem(
-            IWorkItemsGroup workItemsGroup,
-            WIGStartInfo wigStartInfo,
-            WorkItemInfo workItemInfo,
-            WorkItemCallback callback,
-            object state)
-        {
-            ValidateCallback(callback);
-            ValidateCallback(workItemInfo.PostExecuteWorkItemCallback);
-
-            WorkItem workItem = new WorkItem(
-                workItemsGroup,
-                new WorkItemInfo(workItemInfo),
-                callback,
-                state);
-
-            return workItem;
-        }
-
-		/// <summary>
-		/// Create a new work item
-		/// </summary>
-        /// <param name="workItemsGroup">The work items group</param>
-		/// <param name="wigStartInfo">Work item group start information</param>
-		/// <param name="callback">A callback to execute</param>
-		/// <param name="state">
-		/// The context object of the work item. Used for passing arguments to the work item. 
-		/// </param>
-		/// <param name="postExecuteWorkItemCallback">
-		/// A delegate to call after the callback completion
-		/// </param>
-		/// <returns>Returns a work item</returns>
-		public static WorkItem CreateWorkItem(
-			IWorkItemsGroup workItemsGroup,
-			WIGStartInfo wigStartInfo,
-			WorkItemCallback callback, 
-			object state,
-			PostExecuteWorkItemCallback postExecuteWorkItemCallback)
-		{
-			ValidateCallback(callback);
-			ValidateCallback(postExecuteWorkItemCallback);
-
-			WorkItemInfo workItemInfo = new WorkItemInfo();
-			workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
-			workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
-			workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
-			workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
-			workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
-            workItemInfo.WorkItemPriority = wigStartInfo.WorkItemPriority;
-
-			WorkItem workItem = new WorkItem(
-				workItemsGroup,
-				workItemInfo,
-				callback, 
-				state);
-
-			return workItem;
-		}
-
-		/// <summary>
-		/// Create a new work item
-		/// </summary>
-        /// <param name="workItemsGroup">The work items group</param>
-		/// <param name="wigStartInfo">Work item group start information</param>
-		/// <param name="callback">A callback to execute</param>
-		/// <param name="state">
-		/// The context object of the work item. Used for passing arguments to the work item. 
-		/// </param>
-		/// <param name="postExecuteWorkItemCallback">
-		/// A delegate to call after the callback completion
-		/// </param>
-		/// <param name="workItemPriority">The work item priority</param>
-		/// <returns>Returns a work item</returns>
-		public static WorkItem CreateWorkItem(
-			IWorkItemsGroup workItemsGroup,
-			WIGStartInfo wigStartInfo,
-			WorkItemCallback callback, 
-			object state,
-			PostExecuteWorkItemCallback postExecuteWorkItemCallback,
-			WorkItemPriority workItemPriority)
-		{
-			ValidateCallback(callback);
-			ValidateCallback(postExecuteWorkItemCallback);
-
-			WorkItemInfo workItemInfo = new WorkItemInfo();
-			workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
-			workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
-			workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
-			workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
-			workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
-			workItemInfo.WorkItemPriority = workItemPriority;
-
-			WorkItem workItem = new WorkItem(
-				workItemsGroup,
-				workItemInfo,
-				callback, 
-				state);
-
-			return workItem;
-		}
-
-		/// <summary>
-		/// Create a new work item
-		/// </summary>
-        /// <param name="workItemsGroup">The work items group</param>
-		/// <param name="wigStartInfo">Work item group start information</param>
-		/// <param name="callback">A callback to execute</param>
-		/// <param name="state">
-		/// The context object of the work item. Used for passing arguments to the work item. 
-		/// </param>
-		/// <param name="postExecuteWorkItemCallback">
-		/// A delegate to call after the callback completion
-		/// </param>
-		/// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
-		/// <returns>Returns a work item</returns>
-		public static WorkItem CreateWorkItem(
-			IWorkItemsGroup workItemsGroup,
-			WIGStartInfo wigStartInfo,
-			WorkItemCallback callback, 
-			object state,
-			PostExecuteWorkItemCallback postExecuteWorkItemCallback,
-			CallToPostExecute callToPostExecute)
-		{
-			ValidateCallback(callback);
-			ValidateCallback(postExecuteWorkItemCallback);
-
-			WorkItemInfo workItemInfo = new WorkItemInfo();
-			workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
-			workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
-			workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
-			workItemInfo.CallToPostExecute = callToPostExecute;
-			workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
-            workItemInfo.WorkItemPriority = wigStartInfo.WorkItemPriority;
-
-			WorkItem workItem = new WorkItem(
-				workItemsGroup,
-				workItemInfo,
-				callback, 
-				state);
-
-			return workItem;
-		}
-
-		/// <summary>
-		/// Create a new work item
-		/// </summary>
-        /// <param name="workItemsGroup">The work items group</param>
-		/// <param name="wigStartInfo">Work item group start information</param>
-		/// <param name="callback">A callback to execute</param>
-		/// <param name="state">
-		/// The context object of the work item. Used for passing arguments to the work item. 
-		/// </param>
-		/// <param name="postExecuteWorkItemCallback">
-		/// A delegate to call after the callback completion
-		/// </param>
-		/// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
-		/// <param name="workItemPriority">The work item priority</param>
-		/// <returns>Returns a work item</returns>
-		public static WorkItem CreateWorkItem(
-			IWorkItemsGroup workItemsGroup,
-			WIGStartInfo wigStartInfo,
-			WorkItemCallback callback, 
-			object state,
-			PostExecuteWorkItemCallback postExecuteWorkItemCallback,
-			CallToPostExecute callToPostExecute,
-			WorkItemPriority workItemPriority)
-		{
-
-			ValidateCallback(callback);
-			ValidateCallback(postExecuteWorkItemCallback);
-
-			WorkItemInfo workItemInfo = new WorkItemInfo();
-			workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
-			workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
-			workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
-			workItemInfo.CallToPostExecute = callToPostExecute;
-			workItemInfo.WorkItemPriority = workItemPriority;
-			workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
-
-			WorkItem workItem = new WorkItem(
-				workItemsGroup,
-				workItemInfo,
-				callback, 
-				state);
-			
-			return workItem;
-		}
-
-		private static void ValidateCallback(Delegate callback)
-		{
-            if (callback != null && callback.GetInvocationList().Length > 1)
-			{
-				throw new NotSupportedException("SmartThreadPool doesn't support delegates chains");
-			}
-		}
-	}
-
-	#endregion
-}
+using System;
+
+namespace Amib.Threading.Internal
+{
+	#region WorkItemFactory class 
+
+	public class WorkItemFactory
+	{
+		/// <summary>
+		/// Create a new work item
+		/// </summary>
+		/// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
+		/// <param name="wigStartInfo">Work item group start information</param>
+		/// <param name="callback">A callback to execute</param>
+		/// <returns>Returns a work item</returns>
+		public static WorkItem CreateWorkItem(
+			IWorkItemsGroup workItemsGroup,
+			WIGStartInfo wigStartInfo,
+			WorkItemCallback callback)
+		{
+			return CreateWorkItem(workItemsGroup, wigStartInfo, callback, null);
+		}
+
+		/// <summary>
+		/// Create a new work item
+		/// </summary>
+        /// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
+        /// <param name="wigStartInfo">Work item group start information</param>
+		/// <param name="callback">A callback to execute</param>
+		/// <param name="workItemPriority">The priority of the work item</param>
+		/// <returns>Returns a work item</returns>
+		public static WorkItem CreateWorkItem(
+			IWorkItemsGroup workItemsGroup,
+			WIGStartInfo wigStartInfo,
+			WorkItemCallback callback, 
+			WorkItemPriority workItemPriority)
+		{
+			return CreateWorkItem(workItemsGroup, wigStartInfo, callback, null, workItemPriority);
+		}
+
+		/// <summary>
+		/// Create a new work item
+		/// </summary>
+        /// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
+        /// <param name="wigStartInfo">Work item group start information</param>
+		/// <param name="workItemInfo">Work item info</param>
+		/// <param name="callback">A callback to execute</param>
+		/// <returns>Returns a work item</returns>
+		public static WorkItem CreateWorkItem(
+			IWorkItemsGroup workItemsGroup,
+			WIGStartInfo wigStartInfo,
+			WorkItemInfo workItemInfo, 
+			WorkItemCallback callback)
+		{
+			return CreateWorkItem(
+				workItemsGroup,
+				wigStartInfo,
+				workItemInfo, 
+				callback, 
+				null);
+		}
+
+		/// <summary>
+		/// Create a new work item
+		/// </summary>
+        /// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
+        /// <param name="wigStartInfo">Work item group start information</param>
+		/// <param name="callback">A callback to execute</param>
+		/// <param name="state">
+		/// The context object of the work item. Used for passing arguments to the work item. 
+		/// </param>
+		/// <returns>Returns a work item</returns>
+		public static WorkItem CreateWorkItem(
+			IWorkItemsGroup workItemsGroup,
+			WIGStartInfo wigStartInfo,
+			WorkItemCallback callback, 
+			object state)
+		{
+			ValidateCallback(callback);
+            
+			WorkItemInfo workItemInfo = new WorkItemInfo();
+			workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
+			workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
+			workItemInfo.PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback;
+			workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
+			workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
+            workItemInfo.WorkItemPriority = wigStartInfo.WorkItemPriority;
+
+			WorkItem workItem = new WorkItem(
+				workItemsGroup,
+				workItemInfo,
+				callback, 
+				state);
+			return workItem;
+		}
+
+		/// <summary>
+		/// Create a new work item
+		/// </summary>
+		/// <param name="workItemsGroup">The work items group</param>
+		/// <param name="wigStartInfo">Work item group start information</param>
+		/// <param name="callback">A callback to execute</param>
+		/// <param name="state">
+		/// The context object of the work item. Used for passing arguments to the work item. 
+		/// </param>
+		/// <param name="workItemPriority">The work item priority</param>
+		/// <returns>Returns a work item</returns>
+		public static WorkItem CreateWorkItem(
+			IWorkItemsGroup workItemsGroup,
+			WIGStartInfo wigStartInfo,
+			WorkItemCallback callback, 
+			object state, 
+			WorkItemPriority workItemPriority)
+		{
+			ValidateCallback(callback);
+
+			WorkItemInfo workItemInfo = new WorkItemInfo();
+			workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
+			workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
+			workItemInfo.PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback;
+			workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
+			workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
+			workItemInfo.WorkItemPriority = workItemPriority;
+
+			WorkItem workItem = new WorkItem(
+				workItemsGroup,
+				workItemInfo,
+				callback, 
+				state);
+
+			return workItem;
+		}
+
+		/// <summary>
+		/// Create a new work item
+		/// </summary>
+        /// <param name="workItemsGroup">The work items group</param>
+		/// <param name="wigStartInfo">Work item group start information</param>
+		/// <param name="workItemInfo">Work item information</param>
+		/// <param name="callback">A callback to execute</param>
+		/// <param name="state">
+		/// The context object of the work item. Used for passing arguments to the work item. 
+		/// </param>
+		/// <returns>Returns a work item</returns>
+        public static WorkItem CreateWorkItem(
+            IWorkItemsGroup workItemsGroup,
+            WIGStartInfo wigStartInfo,
+            WorkItemInfo workItemInfo,
+            WorkItemCallback callback,
+            object state)
+        {
+            ValidateCallback(callback);
+            ValidateCallback(workItemInfo.PostExecuteWorkItemCallback);
+
+            WorkItem workItem = new WorkItem(
+                workItemsGroup,
+                new WorkItemInfo(workItemInfo),
+                callback,
+                state);
+
+            return workItem;
+        }
+
+		/// <summary>
+		/// Create a new work item
+		/// </summary>
+        /// <param name="workItemsGroup">The work items group</param>
+		/// <param name="wigStartInfo">Work item group start information</param>
+		/// <param name="callback">A callback to execute</param>
+		/// <param name="state">
+		/// The context object of the work item. Used for passing arguments to the work item. 
+		/// </param>
+		/// <param name="postExecuteWorkItemCallback">
+		/// A delegate to call after the callback completion
+		/// </param>
+		/// <returns>Returns a work item</returns>
+		public static WorkItem CreateWorkItem(
+			IWorkItemsGroup workItemsGroup,
+			WIGStartInfo wigStartInfo,
+			WorkItemCallback callback, 
+			object state,
+			PostExecuteWorkItemCallback postExecuteWorkItemCallback)
+		{
+			ValidateCallback(callback);
+			ValidateCallback(postExecuteWorkItemCallback);
+
+			WorkItemInfo workItemInfo = new WorkItemInfo();
+			workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
+			workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
+			workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
+			workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
+			workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
+            workItemInfo.WorkItemPriority = wigStartInfo.WorkItemPriority;
+
+			WorkItem workItem = new WorkItem(
+				workItemsGroup,
+				workItemInfo,
+				callback, 
+				state);
+
+			return workItem;
+		}
+
+		/// <summary>
+		/// Create a new work item
+		/// </summary>
+        /// <param name="workItemsGroup">The work items group</param>
+		/// <param name="wigStartInfo">Work item group start information</param>
+		/// <param name="callback">A callback to execute</param>
+		/// <param name="state">
+		/// The context object of the work item. Used for passing arguments to the work item. 
+		/// </param>
+		/// <param name="postExecuteWorkItemCallback">
+		/// A delegate to call after the callback completion
+		/// </param>
+		/// <param name="workItemPriority">The work item priority</param>
+		/// <returns>Returns a work item</returns>
+		public static WorkItem CreateWorkItem(
+			IWorkItemsGroup workItemsGroup,
+			WIGStartInfo wigStartInfo,
+			WorkItemCallback callback, 
+			object state,
+			PostExecuteWorkItemCallback postExecuteWorkItemCallback,
+			WorkItemPriority workItemPriority)
+		{
+			ValidateCallback(callback);
+			ValidateCallback(postExecuteWorkItemCallback);
+
+			WorkItemInfo workItemInfo = new WorkItemInfo();
+			workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
+			workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
+			workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
+			workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
+			workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
+			workItemInfo.WorkItemPriority = workItemPriority;
+
+			WorkItem workItem = new WorkItem(
+				workItemsGroup,
+				workItemInfo,
+				callback, 
+				state);
+
+			return workItem;
+		}
+
+		/// <summary>
+		/// Create a new work item
+		/// </summary>
+        /// <param name="workItemsGroup">The work items group</param>
+		/// <param name="wigStartInfo">Work item group start information</param>
+		/// <param name="callback">A callback to execute</param>
+		/// <param name="state">
+		/// The context object of the work item. Used for passing arguments to the work item. 
+		/// </param>
+		/// <param name="postExecuteWorkItemCallback">
+		/// A delegate to call after the callback completion
+		/// </param>
+		/// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
+		/// <returns>Returns a work item</returns>
+		public static WorkItem CreateWorkItem(
+			IWorkItemsGroup workItemsGroup,
+			WIGStartInfo wigStartInfo,
+			WorkItemCallback callback, 
+			object state,
+			PostExecuteWorkItemCallback postExecuteWorkItemCallback,
+			CallToPostExecute callToPostExecute)
+		{
+			ValidateCallback(callback);
+			ValidateCallback(postExecuteWorkItemCallback);
+
+			WorkItemInfo workItemInfo = new WorkItemInfo();
+			workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
+			workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
+			workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
+			workItemInfo.CallToPostExecute = callToPostExecute;
+			workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
+            workItemInfo.WorkItemPriority = wigStartInfo.WorkItemPriority;
+
+			WorkItem workItem = new WorkItem(
+				workItemsGroup,
+				workItemInfo,
+				callback, 
+				state);
+
+			return workItem;
+		}
+
+		/// <summary>
+		/// Create a new work item
+		/// </summary>
+        /// <param name="workItemsGroup">The work items group</param>
+		/// <param name="wigStartInfo">Work item group start information</param>
+		/// <param name="callback">A callback to execute</param>
+		/// <param name="state">
+		/// The context object of the work item. Used for passing arguments to the work item. 
+		/// </param>
+		/// <param name="postExecuteWorkItemCallback">
+		/// A delegate to call after the callback completion
+		/// </param>
+		/// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
+		/// <param name="workItemPriority">The work item priority</param>
+		/// <returns>Returns a work item</returns>
+		public static WorkItem CreateWorkItem(
+			IWorkItemsGroup workItemsGroup,
+			WIGStartInfo wigStartInfo,
+			WorkItemCallback callback, 
+			object state,
+			PostExecuteWorkItemCallback postExecuteWorkItemCallback,
+			CallToPostExecute callToPostExecute,
+			WorkItemPriority workItemPriority)
+		{
+
+			ValidateCallback(callback);
+			ValidateCallback(postExecuteWorkItemCallback);
+
+			WorkItemInfo workItemInfo = new WorkItemInfo();
+			workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
+			workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
+			workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
+			workItemInfo.CallToPostExecute = callToPostExecute;
+			workItemInfo.WorkItemPriority = workItemPriority;
+			workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
+
+			WorkItem workItem = new WorkItem(
+				workItemsGroup,
+				workItemInfo,
+				callback, 
+				state);
+			
+			return workItem;
+		}
+
+		private static void ValidateCallback(Delegate callback)
+		{
+            if (callback != null && callback.GetInvocationList().Length > 1)
+			{
+				throw new NotSupportedException("SmartThreadPool doesn't support delegates chains");
+			}
+		}
+	}
+
+	#endregion
+}

+ 69 - 69
ThirdParty/SmartThreadPool/WorkItemInfo.cs

@@ -1,69 +1,69 @@
-namespace Amib.Threading
-{
-	#region WorkItemInfo class
-
-	/// <summary>
-	/// Summary description for WorkItemInfo.
-	/// </summary>
-	public class WorkItemInfo
-	{
-	    public WorkItemInfo()
-		{
-			UseCallerCallContext = SmartThreadPool.DefaultUseCallerCallContext;
-			UseCallerHttpContext = SmartThreadPool.DefaultUseCallerHttpContext;
-			DisposeOfStateObjects = SmartThreadPool.DefaultDisposeOfStateObjects;
-			CallToPostExecute = SmartThreadPool.DefaultCallToPostExecute;
-			PostExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback;
-			WorkItemPriority = SmartThreadPool.DefaultWorkItemPriority;
-		}
-
-		public WorkItemInfo(WorkItemInfo workItemInfo)
-		{
-			UseCallerCallContext = workItemInfo.UseCallerCallContext;
-			UseCallerHttpContext = workItemInfo.UseCallerHttpContext;
-			DisposeOfStateObjects = workItemInfo.DisposeOfStateObjects;
-			CallToPostExecute = workItemInfo.CallToPostExecute;
-			PostExecuteWorkItemCallback = workItemInfo.PostExecuteWorkItemCallback;
-			WorkItemPriority = workItemInfo.WorkItemPriority;
-            Timeout = workItemInfo.Timeout;
-		}
-
-	    /// <summary>
-	    /// Get/Set if to use the caller's security context
-	    /// </summary>
-	    public bool UseCallerCallContext { get; set; }
-
-	    /// <summary>
-	    /// Get/Set if to use the caller's HTTP context
-	    /// </summary>
-	    public bool UseCallerHttpContext { get; set; }
-
-	    /// <summary>
-	    /// Get/Set if to dispose of the state object of a work item
-	    /// </summary>
-	    public bool DisposeOfStateObjects { get; set; }
-
-	    /// <summary>
-	    /// Get/Set the run the post execute options
-	    /// </summary>
-        public CallToPostExecute CallToPostExecute { get; set; }
-
-	    /// <summary>
-	    /// Get/Set the post execute callback
-	    /// </summary>
-        public PostExecuteWorkItemCallback PostExecuteWorkItemCallback { get; set; }
-
-	    /// <summary>
-	    /// Get/Set the work item's priority
-	    /// </summary>
-	    public WorkItemPriority WorkItemPriority { get; set; }
-
-	    /// <summary>
-	    /// Get/Set the work item's timout in milliseconds.
-        /// This is a passive timout. When the timout expires the work item won't be actively aborted!
-	    /// </summary>
-	    public long Timeout { get; set; }
-	}
-
-	#endregion
-}
+namespace Amib.Threading
+{
+	#region WorkItemInfo class
+
+	/// <summary>
+	/// Summary description for WorkItemInfo.
+	/// </summary>
+	public class WorkItemInfo
+	{
+	    public WorkItemInfo()
+		{
+			UseCallerCallContext = SmartThreadPool.DefaultUseCallerCallContext;
+			UseCallerHttpContext = SmartThreadPool.DefaultUseCallerHttpContext;
+			DisposeOfStateObjects = SmartThreadPool.DefaultDisposeOfStateObjects;
+			CallToPostExecute = SmartThreadPool.DefaultCallToPostExecute;
+			PostExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback;
+			WorkItemPriority = SmartThreadPool.DefaultWorkItemPriority;
+		}
+
+		public WorkItemInfo(WorkItemInfo workItemInfo)
+		{
+			UseCallerCallContext = workItemInfo.UseCallerCallContext;
+			UseCallerHttpContext = workItemInfo.UseCallerHttpContext;
+			DisposeOfStateObjects = workItemInfo.DisposeOfStateObjects;
+			CallToPostExecute = workItemInfo.CallToPostExecute;
+			PostExecuteWorkItemCallback = workItemInfo.PostExecuteWorkItemCallback;
+			WorkItemPriority = workItemInfo.WorkItemPriority;
+            Timeout = workItemInfo.Timeout;
+		}
+
+	    /// <summary>
+	    /// Get/Set if to use the caller's security context
+	    /// </summary>
+	    public bool UseCallerCallContext { get; set; }
+
+	    /// <summary>
+	    /// Get/Set if to use the caller's HTTP context
+	    /// </summary>
+	    public bool UseCallerHttpContext { get; set; }
+
+	    /// <summary>
+	    /// Get/Set if to dispose of the state object of a work item
+	    /// </summary>
+	    public bool DisposeOfStateObjects { get; set; }
+
+	    /// <summary>
+	    /// Get/Set the run the post execute options
+	    /// </summary>
+        public CallToPostExecute CallToPostExecute { get; set; }
+
+	    /// <summary>
+	    /// Get/Set the post execute callback
+	    /// </summary>
+        public PostExecuteWorkItemCallback PostExecuteWorkItemCallback { get; set; }
+
+	    /// <summary>
+	    /// Get/Set the work item's priority
+	    /// </summary>
+	    public WorkItemPriority WorkItemPriority { get; set; }
+
+	    /// <summary>
+	    /// Get/Set the work item's timout in milliseconds.
+        /// This is a passive timout. When the timout expires the work item won't be actively aborted!
+	    /// </summary>
+	    public long Timeout { get; set; }
+	}
+
+	#endregion
+}

+ 128 - 128
ThirdParty/SmartThreadPool/WorkItemResultTWrapper.cs

@@ -1,128 +1,128 @@
-using System;
-using System.Threading;
-
-namespace Amib.Threading.Internal
-{
-    #region WorkItemResultTWrapper class
-
-    internal class WorkItemResultTWrapper<TResult> : IWorkItemResult<TResult>, IInternalWaitableResult
-    {
-        private readonly IWorkItemResult _workItemResult;
-
-        public WorkItemResultTWrapper(IWorkItemResult workItemResult)
-        {
-            _workItemResult = workItemResult;
-        }
-
-        #region IWorkItemResult<TResult> Members
-
-        public TResult GetResult()
-        {
-            return (TResult)_workItemResult.GetResult();
-        }
-
-        public TResult GetResult(int millisecondsTimeout, bool exitContext)
-        {
-            return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext);
-        }
-
-        public TResult GetResult(TimeSpan timeout, bool exitContext)
-        {
-            return (TResult)_workItemResult.GetResult(timeout, exitContext);
-        }
-
-        public TResult GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle)
-        {
-            return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle);
-        }
-
-        public TResult GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle)
-        {
-            return (TResult)_workItemResult.GetResult(timeout, exitContext, cancelWaitHandle);
-        }
-
-        public TResult GetResult(out Exception e)
-        {
-            return (TResult)_workItemResult.GetResult(out e);
-        }
-
-        public TResult GetResult(int millisecondsTimeout, bool exitContext, out Exception e)
-        {
-            return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext, out e);
-        }
-
-        public TResult GetResult(TimeSpan timeout, bool exitContext, out Exception e)
-        {
-            return (TResult)_workItemResult.GetResult(timeout, exitContext, out e);
-        }
-
-        public TResult GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
-        {
-            return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e);
-        }
-
-        public TResult GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
-        {
-            return (TResult)_workItemResult.GetResult(timeout, exitContext, cancelWaitHandle, out e);
-        }
-
-        public bool IsCompleted
-        {
-            get { return _workItemResult.IsCompleted; }
-        }
-
-        public bool IsCanceled
-        {
-            get { return _workItemResult.IsCanceled; }
-        }
-
-        public object State
-        {
-            get { return _workItemResult.State; }
-        }
-
-        public bool Cancel()
-        {
-            return _workItemResult.Cancel();
-        }
-
-        public bool Cancel(bool abortExecution)
-        {
-            return _workItemResult.Cancel(abortExecution);
-        }
-
-        public WorkItemPriority WorkItemPriority
-        {
-            get { return _workItemResult.WorkItemPriority; }
-        }
-
-        public TResult Result
-        {
-            get { return (TResult)_workItemResult.Result; }
-        }
-
-        public object Exception
-        {
-            get { return (TResult)_workItemResult.Exception; }
-        }
-
-        #region IInternalWorkItemResult Members
-
-        public IWorkItemResult GetWorkItemResult()
-        {
-            return _workItemResult.GetWorkItemResult();
-        }
-
-        public IWorkItemResult<TRes> GetWorkItemResultT<TRes>()
-        {
-            return (IWorkItemResult<TRes>)this;
-        }
-
-        #endregion
-
-        #endregion
-    }
-
-    #endregion
-
-}
+using System;
+using System.Threading;
+
+namespace Amib.Threading.Internal
+{
+    #region WorkItemResultTWrapper class
+
+    internal class WorkItemResultTWrapper<TResult> : IWorkItemResult<TResult>, IInternalWaitableResult
+    {
+        private readonly IWorkItemResult _workItemResult;
+
+        public WorkItemResultTWrapper(IWorkItemResult workItemResult)
+        {
+            _workItemResult = workItemResult;
+        }
+
+        #region IWorkItemResult<TResult> Members
+
+        public TResult GetResult()
+        {
+            return (TResult)_workItemResult.GetResult();
+        }
+
+        public TResult GetResult(int millisecondsTimeout, bool exitContext)
+        {
+            return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext);
+        }
+
+        public TResult GetResult(TimeSpan timeout, bool exitContext)
+        {
+            return (TResult)_workItemResult.GetResult(timeout, exitContext);
+        }
+
+        public TResult GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle)
+        {
+            return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle);
+        }
+
+        public TResult GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle)
+        {
+            return (TResult)_workItemResult.GetResult(timeout, exitContext, cancelWaitHandle);
+        }
+
+        public TResult GetResult(out Exception e)
+        {
+            return (TResult)_workItemResult.GetResult(out e);
+        }
+
+        public TResult GetResult(int millisecondsTimeout, bool exitContext, out Exception e)
+        {
+            return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext, out e);
+        }
+
+        public TResult GetResult(TimeSpan timeout, bool exitContext, out Exception e)
+        {
+            return (TResult)_workItemResult.GetResult(timeout, exitContext, out e);
+        }
+
+        public TResult GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
+        {
+            return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e);
+        }
+
+        public TResult GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
+        {
+            return (TResult)_workItemResult.GetResult(timeout, exitContext, cancelWaitHandle, out e);
+        }
+
+        public bool IsCompleted
+        {
+            get { return _workItemResult.IsCompleted; }
+        }
+
+        public bool IsCanceled
+        {
+            get { return _workItemResult.IsCanceled; }
+        }
+
+        public object State
+        {
+            get { return _workItemResult.State; }
+        }
+
+        public bool Cancel()
+        {
+            return _workItemResult.Cancel();
+        }
+
+        public bool Cancel(bool abortExecution)
+        {
+            return _workItemResult.Cancel(abortExecution);
+        }
+
+        public WorkItemPriority WorkItemPriority
+        {
+            get { return _workItemResult.WorkItemPriority; }
+        }
+
+        public TResult Result
+        {
+            get { return (TResult)_workItemResult.Result; }
+        }
+
+        public object Exception
+        {
+            get { return (TResult)_workItemResult.Exception; }
+        }
+
+        #region IInternalWorkItemResult Members
+
+        public IWorkItemResult GetWorkItemResult()
+        {
+            return _workItemResult.GetWorkItemResult();
+        }
+
+        public IWorkItemResult<TRes> GetWorkItemResultT<TRes>()
+        {
+            return (IWorkItemResult<TRes>)this;
+        }
+
+        #endregion
+
+        #endregion
+    }
+
+    #endregion
+
+}

+ 361 - 361
ThirdParty/SmartThreadPool/WorkItemsGroup.cs

@@ -1,361 +1,361 @@
-using System;
-using System.Threading;
-using System.Runtime.CompilerServices;
-using System.Diagnostics;
-
-namespace Amib.Threading.Internal
-{
-
-	#region WorkItemsGroup class 
-
-	/// <summary>
-	/// Summary description for WorkItemsGroup.
-	/// </summary>
-	public class WorkItemsGroup : WorkItemsGroupBase
-	{
-		#region Private members
-
-		private readonly object _lock = new object();
-
-		/// <summary>
-		/// A reference to the SmartThreadPool instance that created this 
-		/// WorkItemsGroup.
-		/// </summary>
-		private readonly SmartThreadPool _stp;
-
-		/// <summary>
-		/// The OnIdle event
-		/// </summary>
-		private event WorkItemsGroupIdleHandler _onIdle;
-
-        /// <summary>
-        /// A flag to indicate if the Work Items Group is now suspended.
-        /// </summary>
-        private bool _isSuspended;
-
-		/// <summary>
-		/// Defines how many work items of this WorkItemsGroup can run at once.
-		/// </summary>
-		private int _concurrency;
-
-		/// <summary>
-		/// Priority queue to hold work items before they are passed 
-		/// to the SmartThreadPool.
-		/// </summary>
-		private readonly PriorityQueue _workItemsQueue;
-
-		/// <summary>
-		/// Indicate how many work items are waiting in the SmartThreadPool
-		/// queue.
-		/// This value is used to apply the concurrency.
-		/// </summary>
-		private int _workItemsInStpQueue;
-
-		/// <summary>
-		/// Indicate how many work items are currently running in the SmartThreadPool.
-		/// This value is used with the Cancel, to calculate if we can send new 
-		/// work items to the STP.
-		/// </summary>
-		private int _workItemsExecutingInStp = 0;
-
-		/// <summary>
-		/// WorkItemsGroup start information
-		/// </summary>
-		private readonly WIGStartInfo _workItemsGroupStartInfo;
-
-		/// <summary>
-		/// Signaled when all of the WorkItemsGroup's work item completed.
-		/// </summary>
-        //private readonly ManualResetEvent _isIdleWaitHandle = new ManualResetEvent(true);
-        private readonly ManualResetEvent _isIdleWaitHandle = EventWaitHandleFactory.CreateManualResetEvent(true);
-
-		/// <summary>
-		/// A common object for all the work items that this work items group
-		/// generate so we can mark them to cancel in O(1)
-		/// </summary>
-		private CanceledWorkItemsGroup _canceledWorkItemsGroup = new CanceledWorkItemsGroup();
-
-		#endregion 
-
-		#region Construction
-
-	    public WorkItemsGroup(
-			SmartThreadPool stp, 
-			int concurrency, 
-			WIGStartInfo wigStartInfo)
-		{
-			if (concurrency <= 0)
-			{
-				throw new ArgumentOutOfRangeException(
-                    "concurrency",
-#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
-                    concurrency,
-#endif
- "concurrency must be greater than zero");
-			}
-			_stp = stp;
-			_concurrency = concurrency;
-			_workItemsGroupStartInfo = new WIGStartInfo(wigStartInfo).AsReadOnly();
-			_workItemsQueue = new PriorityQueue();
-	        Name = "WorkItemsGroup";
-
-			// The _workItemsInStpQueue gets the number of currently executing work items,
-			// because once a work item is executing, it cannot be cancelled.
-			_workItemsInStpQueue = _workItemsExecutingInStp;
-
-            _isSuspended = _workItemsGroupStartInfo.StartSuspended;
-		}
-
-		#endregion 
-
-        #region WorkItemsGroupBase Overrides
-
-        public override int Concurrency
-        {
-            get { return _concurrency; }
-            set
-            {
-                Debug.Assert(value > 0);
-
-                int diff = value - _concurrency;
-                _concurrency = value;
-                if (diff > 0)
-                {
-                    EnqueueToSTPNextNWorkItem(diff);
-                }
-            }
-        }
-
-        public override int WaitingCallbacks
-        {
-            get { return _workItemsQueue.Count; }
-        }
-
-        public override object[] GetStates()
-        {
-            lock (_lock)
-            {
-                object[] states = new object[_workItemsQueue.Count];
-                int i = 0;
-                foreach (WorkItem workItem in _workItemsQueue)
-                {
-                    states[i] = workItem.GetWorkItemResult().State;
-                    ++i;
-                }
-                return states;
-            }
-        }
-
-	    /// <summary>
-        /// WorkItemsGroup start information
-        /// </summary>
-        public override WIGStartInfo WIGStartInfo
-        {
-            get { return _workItemsGroupStartInfo; }
-        }
-
-	    /// <summary>
-	    /// Start the Work Items Group if it was started suspended
-	    /// </summary>
-	    public override void Start()
-	    {
-	        // If the Work Items Group already started then quit
-	        if (!_isSuspended)
-	        {
-	            return;
-	        }
-	        _isSuspended = false;
-            
-	        EnqueueToSTPNextNWorkItem(Math.Min(_workItemsQueue.Count, _concurrency));
-	    }
-
-	    public override void Cancel(bool abortExecution)
-	    {
-	        lock (_lock)
-	        {
-	            _canceledWorkItemsGroup.IsCanceled = true;
-	            _workItemsQueue.Clear();
-	            _workItemsInStpQueue = 0;
-	            _canceledWorkItemsGroup = new CanceledWorkItemsGroup();
-	        }
-
-	        if (abortExecution)
-	        {
-	            _stp.CancelAbortWorkItemsGroup(this);
-	        }
-	    }
-
-	    /// <summary>
-        /// Wait for the thread pool to be idle
-        /// </summary>
-        public override bool WaitForIdle(int millisecondsTimeout)
-        {
-            SmartThreadPool.ValidateWorkItemsGroupWaitForIdle(this);
-            return STPEventWaitHandle.WaitOne(_isIdleWaitHandle, millisecondsTimeout, false);
-        }
-
-	    public override event WorkItemsGroupIdleHandler OnIdle
-		{
-			add { _onIdle += value; }
-			remove { _onIdle -= value; }
-		}
-
-	    #endregion 
-
-		#region Private methods
-
-	    private void RegisterToWorkItemCompletion(IWorkItemResult wir)
-		{
-			IInternalWorkItemResult iwir = (IInternalWorkItemResult)wir;
-			iwir.OnWorkItemStarted += OnWorkItemStartedCallback;
-			iwir.OnWorkItemCompleted += OnWorkItemCompletedCallback;
-		}
-
-	    public void OnSTPIsStarting()
-		{
-            if (_isSuspended)
-            {
-                return;
-            }
-			
-            EnqueueToSTPNextNWorkItem(_concurrency);
-		}
-
-	    public void EnqueueToSTPNextNWorkItem(int count)
-        {
-            for (int i = 0; i < count; ++i)
-            {
-                EnqueueToSTPNextWorkItem(null, false);
-            }
-        }
-
-		private object FireOnIdle(object state)
-		{
-			FireOnIdleImpl(_onIdle);
-			return null;
-		}
-
-		[MethodImpl(MethodImplOptions.NoInlining)]
-		private void FireOnIdleImpl(WorkItemsGroupIdleHandler onIdle)
-		{
-			if(null == onIdle)
-			{
-				return;
-			}
-
-			Delegate[] delegates = onIdle.GetInvocationList();
-			foreach(WorkItemsGroupIdleHandler eh in delegates)
-			{
-				try
-				{
-					eh(this);
-				}
-                catch { }  // Suppress exceptions
-			}
-		}
-
-		private void OnWorkItemStartedCallback(WorkItem workItem)
-		{
-			lock(_lock)
-			{
-				++_workItemsExecutingInStp;
-			}
-		}
-
-		private void OnWorkItemCompletedCallback(WorkItem workItem)
-		{
-			EnqueueToSTPNextWorkItem(null, true);
-		}
-
-        internal override void Enqueue(WorkItem workItem)
-        {
-            EnqueueToSTPNextWorkItem(workItem);
-        }
-
-	    private void EnqueueToSTPNextWorkItem(WorkItem workItem)
-		{
-			EnqueueToSTPNextWorkItem(workItem, false);
-		}
-
-		private void EnqueueToSTPNextWorkItem(WorkItem workItem, bool decrementWorkItemsInStpQueue)
-		{
-			lock(_lock)
-			{
-				// Got here from OnWorkItemCompletedCallback()
-				if (decrementWorkItemsInStpQueue)
-				{
-					--_workItemsInStpQueue;
-
-					if(_workItemsInStpQueue < 0)
-					{
-						_workItemsInStpQueue = 0;
-					}
-
-					--_workItemsExecutingInStp;
-
-					if(_workItemsExecutingInStp < 0)
-					{
-						_workItemsExecutingInStp = 0;
-					}
-				}
-
-				// If the work item is not null then enqueue it
-				if (null != workItem)
-				{
-					workItem.CanceledWorkItemsGroup = _canceledWorkItemsGroup;
-
-					RegisterToWorkItemCompletion(workItem.GetWorkItemResult());
-					_workItemsQueue.Enqueue(workItem);
-					//_stp.IncrementWorkItemsCount();
-
-					if ((1 == _workItemsQueue.Count) && 
-						(0 == _workItemsInStpQueue))
-					{
-						_stp.RegisterWorkItemsGroup(this);
-                        IsIdle = false;
-                        _isIdleWaitHandle.Reset();
-					}
-				}
-
-				// If the work items queue of the group is empty than quit
-				if (0 == _workItemsQueue.Count)
-				{
-					if (0 == _workItemsInStpQueue)
-					{
-						_stp.UnregisterWorkItemsGroup(this);
-                        IsIdle = true;
-                        _isIdleWaitHandle.Set();
-                        if (decrementWorkItemsInStpQueue && _onIdle != null && _onIdle.GetInvocationList().Length > 0)
-                        {
-                            _stp.QueueWorkItem(new WorkItemCallback(FireOnIdle));
-                        }
-					}
-					return;
-				}
-
-                if (!_isSuspended)
-				{
-					if (_workItemsInStpQueue < _concurrency)
-					{
-						WorkItem nextWorkItem = _workItemsQueue.Dequeue() as WorkItem;
-                        try
-                        {
-                            _stp.Enqueue(nextWorkItem);
-                        }
-                        catch (ObjectDisposedException e)
-                        {
-                            e.GetHashCode();
-                            // The STP has been shutdown
-                        }
-
-						++_workItemsInStpQueue;
-					}
-				}
-			}
-		}
-
-		#endregion
-    }
-
-	#endregion
-}
+using System;
+using System.Threading;
+using System.Runtime.CompilerServices;
+using System.Diagnostics;
+
+namespace Amib.Threading.Internal
+{
+
+	#region WorkItemsGroup class 
+
+	/// <summary>
+	/// Summary description for WorkItemsGroup.
+	/// </summary>
+	public class WorkItemsGroup : WorkItemsGroupBase
+	{
+		#region Private members
+
+		private readonly object _lock = new object();
+
+		/// <summary>
+		/// A reference to the SmartThreadPool instance that created this 
+		/// WorkItemsGroup.
+		/// </summary>
+		private readonly SmartThreadPool _stp;
+
+		/// <summary>
+		/// The OnIdle event
+		/// </summary>
+		private event WorkItemsGroupIdleHandler _onIdle;
+
+        /// <summary>
+        /// A flag to indicate if the Work Items Group is now suspended.
+        /// </summary>
+        private bool _isSuspended;
+
+		/// <summary>
+		/// Defines how many work items of this WorkItemsGroup can run at once.
+		/// </summary>
+		private int _concurrency;
+
+		/// <summary>
+		/// Priority queue to hold work items before they are passed 
+		/// to the SmartThreadPool.
+		/// </summary>
+		private readonly PriorityQueue _workItemsQueue;
+
+		/// <summary>
+		/// Indicate how many work items are waiting in the SmartThreadPool
+		/// queue.
+		/// This value is used to apply the concurrency.
+		/// </summary>
+		private int _workItemsInStpQueue;
+
+		/// <summary>
+		/// Indicate how many work items are currently running in the SmartThreadPool.
+		/// This value is used with the Cancel, to calculate if we can send new 
+		/// work items to the STP.
+		/// </summary>
+		private int _workItemsExecutingInStp = 0;
+
+		/// <summary>
+		/// WorkItemsGroup start information
+		/// </summary>
+		private readonly WIGStartInfo _workItemsGroupStartInfo;
+
+		/// <summary>
+		/// Signaled when all of the WorkItemsGroup's work item completed.
+		/// </summary>
+        //private readonly ManualResetEvent _isIdleWaitHandle = new ManualResetEvent(true);
+        private readonly ManualResetEvent _isIdleWaitHandle = EventWaitHandleFactory.CreateManualResetEvent(true);
+
+		/// <summary>
+		/// A common object for all the work items that this work items group
+		/// generate so we can mark them to cancel in O(1)
+		/// </summary>
+		private CanceledWorkItemsGroup _canceledWorkItemsGroup = new CanceledWorkItemsGroup();
+
+		#endregion 
+
+		#region Construction
+
+	    public WorkItemsGroup(
+			SmartThreadPool stp, 
+			int concurrency, 
+			WIGStartInfo wigStartInfo)
+		{
+			if (concurrency <= 0)
+			{
+				throw new ArgumentOutOfRangeException(
+                    "concurrency",
+#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
+                    concurrency,
+#endif
+ "concurrency must be greater than zero");
+			}
+			_stp = stp;
+			_concurrency = concurrency;
+			_workItemsGroupStartInfo = new WIGStartInfo(wigStartInfo).AsReadOnly();
+			_workItemsQueue = new PriorityQueue();
+	        Name = "WorkItemsGroup";
+
+			// The _workItemsInStpQueue gets the number of currently executing work items,
+			// because once a work item is executing, it cannot be cancelled.
+			_workItemsInStpQueue = _workItemsExecutingInStp;
+
+            _isSuspended = _workItemsGroupStartInfo.StartSuspended;
+		}
+
+		#endregion 
+
+        #region WorkItemsGroupBase Overrides
+
+        public override int Concurrency
+        {
+            get { return _concurrency; }
+            set
+            {
+                Debug.Assert(value > 0);
+
+                int diff = value - _concurrency;
+                _concurrency = value;
+                if (diff > 0)
+                {
+                    EnqueueToSTPNextNWorkItem(diff);
+                }
+            }
+        }
+
+        public override int WaitingCallbacks
+        {
+            get { return _workItemsQueue.Count; }
+        }
+
+        public override object[] GetStates()
+        {
+            lock (_lock)
+            {
+                object[] states = new object[_workItemsQueue.Count];
+                int i = 0;
+                foreach (WorkItem workItem in _workItemsQueue)
+                {
+                    states[i] = workItem.GetWorkItemResult().State;
+                    ++i;
+                }
+                return states;
+            }
+        }
+
+	    /// <summary>
+        /// WorkItemsGroup start information
+        /// </summary>
+        public override WIGStartInfo WIGStartInfo
+        {
+            get { return _workItemsGroupStartInfo; }
+        }
+
+	    /// <summary>
+	    /// Start the Work Items Group if it was started suspended
+	    /// </summary>
+	    public override void Start()
+	    {
+	        // If the Work Items Group already started then quit
+	        if (!_isSuspended)
+	        {
+	            return;
+	        }
+	        _isSuspended = false;
+            
+	        EnqueueToSTPNextNWorkItem(Math.Min(_workItemsQueue.Count, _concurrency));
+	    }
+
+	    public override void Cancel(bool abortExecution)
+	    {
+	        lock (_lock)
+	        {
+	            _canceledWorkItemsGroup.IsCanceled = true;
+	            _workItemsQueue.Clear();
+	            _workItemsInStpQueue = 0;
+	            _canceledWorkItemsGroup = new CanceledWorkItemsGroup();
+	        }
+
+	        if (abortExecution)
+	        {
+	            _stp.CancelAbortWorkItemsGroup(this);
+	        }
+	    }
+
+	    /// <summary>
+        /// Wait for the thread pool to be idle
+        /// </summary>
+        public override bool WaitForIdle(int millisecondsTimeout)
+        {
+            SmartThreadPool.ValidateWorkItemsGroupWaitForIdle(this);
+            return STPEventWaitHandle.WaitOne(_isIdleWaitHandle, millisecondsTimeout, false);
+        }
+
+	    public override event WorkItemsGroupIdleHandler OnIdle
+		{
+			add { _onIdle += value; }
+			remove { _onIdle -= value; }
+		}
+
+	    #endregion 
+
+		#region Private methods
+
+	    private void RegisterToWorkItemCompletion(IWorkItemResult wir)
+		{
+			IInternalWorkItemResult iwir = (IInternalWorkItemResult)wir;
+			iwir.OnWorkItemStarted += OnWorkItemStartedCallback;
+			iwir.OnWorkItemCompleted += OnWorkItemCompletedCallback;
+		}
+
+	    public void OnSTPIsStarting()
+		{
+            if (_isSuspended)
+            {
+                return;
+            }
+			
+            EnqueueToSTPNextNWorkItem(_concurrency);
+		}
+
+	    public void EnqueueToSTPNextNWorkItem(int count)
+        {
+            for (int i = 0; i < count; ++i)
+            {
+                EnqueueToSTPNextWorkItem(null, false);
+            }
+        }
+
+		private object FireOnIdle(object state)
+		{
+			FireOnIdleImpl(_onIdle);
+			return null;
+		}
+
+		[MethodImpl(MethodImplOptions.NoInlining)]
+		private void FireOnIdleImpl(WorkItemsGroupIdleHandler onIdle)
+		{
+			if(null == onIdle)
+			{
+				return;
+			}
+
+			Delegate[] delegates = onIdle.GetInvocationList();
+			foreach(WorkItemsGroupIdleHandler eh in delegates)
+			{
+				try
+				{
+					eh(this);
+				}
+                catch { }  // Suppress exceptions
+			}
+		}
+
+		private void OnWorkItemStartedCallback(WorkItem workItem)
+		{
+			lock(_lock)
+			{
+				++_workItemsExecutingInStp;
+			}
+		}
+
+		private void OnWorkItemCompletedCallback(WorkItem workItem)
+		{
+			EnqueueToSTPNextWorkItem(null, true);
+		}
+
+        internal override void Enqueue(WorkItem workItem)
+        {
+            EnqueueToSTPNextWorkItem(workItem);
+        }
+
+	    private void EnqueueToSTPNextWorkItem(WorkItem workItem)
+		{
+			EnqueueToSTPNextWorkItem(workItem, false);
+		}
+
+		private void EnqueueToSTPNextWorkItem(WorkItem workItem, bool decrementWorkItemsInStpQueue)
+		{
+			lock(_lock)
+			{
+				// Got here from OnWorkItemCompletedCallback()
+				if (decrementWorkItemsInStpQueue)
+				{
+					--_workItemsInStpQueue;
+
+					if(_workItemsInStpQueue < 0)
+					{
+						_workItemsInStpQueue = 0;
+					}
+
+					--_workItemsExecutingInStp;
+
+					if(_workItemsExecutingInStp < 0)
+					{
+						_workItemsExecutingInStp = 0;
+					}
+				}
+
+				// If the work item is not null then enqueue it
+				if (null != workItem)
+				{
+					workItem.CanceledWorkItemsGroup = _canceledWorkItemsGroup;
+
+					RegisterToWorkItemCompletion(workItem.GetWorkItemResult());
+					_workItemsQueue.Enqueue(workItem);
+					//_stp.IncrementWorkItemsCount();
+
+					if ((1 == _workItemsQueue.Count) && 
+						(0 == _workItemsInStpQueue))
+					{
+						_stp.RegisterWorkItemsGroup(this);
+                        IsIdle = false;
+                        _isIdleWaitHandle.Reset();
+					}
+				}
+
+				// If the work items queue of the group is empty than quit
+				if (0 == _workItemsQueue.Count)
+				{
+					if (0 == _workItemsInStpQueue)
+					{
+						_stp.UnregisterWorkItemsGroup(this);
+                        IsIdle = true;
+                        _isIdleWaitHandle.Set();
+                        if (decrementWorkItemsInStpQueue && _onIdle != null && _onIdle.GetInvocationList().Length > 0)
+                        {
+                            _stp.QueueWorkItem(new WorkItemCallback(FireOnIdle));
+                        }
+					}
+					return;
+				}
+
+                if (!_isSuspended)
+				{
+					if (_workItemsInStpQueue < _concurrency)
+					{
+						WorkItem nextWorkItem = _workItemsQueue.Dequeue() as WorkItem;
+                        try
+                        {
+                            _stp.Enqueue(nextWorkItem);
+                        }
+                        catch (ObjectDisposedException e)
+                        {
+                            e.GetHashCode();
+                            // The STP has been shutdown
+                        }
+
+						++_workItemsInStpQueue;
+					}
+				}
+			}
+		}
+
+		#endregion
+    }
+
+	#endregion
+}

+ 470 - 470
ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs

@@ -1,471 +1,471 @@
-using System;
-using System.Threading;
-
-namespace Amib.Threading.Internal
-{
-    public abstract class WorkItemsGroupBase : IWorkItemsGroup
-    {
-        #region Private Fields
-
-        /// <summary>
-        /// Contains the name of this instance of SmartThreadPool.
-        /// Can be changed by the user.
-        /// </summary>
-        private string _name = "WorkItemsGroupBase";
-
-        public WorkItemsGroupBase()
-        {
-            IsIdle = true;
-        }
-
-        #endregion
-
-        #region IWorkItemsGroup Members
-
-        #region Public Methods
-
-        /// <summary>
-        /// Get/Set the name of the SmartThreadPool/WorkItemsGroup instance
-        /// </summary>
-        public string Name
-        {
-            get { return _name; }
-            set { _name = value; }
-        }
-
-        #endregion
-
-        #region Abstract Methods
-
-        public abstract int Concurrency { get; set; }
-        public abstract int WaitingCallbacks { get; }
-        public abstract object[] GetStates();
-        public abstract WIGStartInfo WIGStartInfo { get; }
-        public abstract void Start();
-        public abstract void Cancel(bool abortExecution);
-        public abstract bool WaitForIdle(int millisecondsTimeout);
-        public abstract event WorkItemsGroupIdleHandler OnIdle;
-
-        internal abstract void Enqueue(WorkItem workItem);
-        internal virtual void PreQueueWorkItem() { }
-
-        #endregion
-
-        #region Common Base Methods
-
-        /// <summary>
-        /// Cancel all the work items.
-        /// Same as Cancel(false)
-        /// </summary>
-        public virtual void Cancel()
-        {
-            Cancel(false);
-        }
-
-        /// <summary>
-        /// Wait for the SmartThreadPool/WorkItemsGroup to be idle
-        /// </summary>
-        public void WaitForIdle()
-        {
-            WaitForIdle(Timeout.Infinite);
-        }
-
-        /// <summary>
-        /// Wait for the SmartThreadPool/WorkItemsGroup to be idle
-        /// </summary>
-        public bool WaitForIdle(TimeSpan timeout)
-        {
-            return WaitForIdle((int)timeout.TotalMilliseconds);
-        }
-
-        /// <summary>
-        /// IsIdle is true when there are no work items running or queued.
-        /// </summary>
-        public bool IsIdle { get; protected set; }
-
-        #endregion
-
-        #region QueueWorkItem
-
-        /// <summary>
-        /// Queue a work item
-        /// </summary>
-        /// <param name="callback">A callback to execute</param>
-        /// <returns>Returns a work item result</returns>
-        public IWorkItemResult QueueWorkItem(WorkItemCallback callback)
-        {
-            WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback);
-            Enqueue(workItem);
-            return workItem.GetWorkItemResult();
-        }
-
-        /// <summary>
-        /// Queue a work item
-        /// </summary>
-        /// <param name="callback">A callback to execute</param>
-        /// <param name="workItemPriority">The priority of the work item</param>
-        /// <returns>Returns a work item result</returns>
-        public IWorkItemResult QueueWorkItem(WorkItemCallback callback, WorkItemPriority workItemPriority)
-        {
-            PreQueueWorkItem();
-            WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, workItemPriority);
-            Enqueue(workItem);
-            return workItem.GetWorkItemResult();
-        }
-
-        /// <summary>
-        /// Queue a work item
-        /// </summary>
-        /// <param name="workItemInfo">Work item info</param>
-        /// <param name="callback">A callback to execute</param>
-        /// <returns>Returns a work item result</returns>
-        public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback)
-        {
-            PreQueueWorkItem();
-            WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback);
-            Enqueue(workItem);
-            return workItem.GetWorkItemResult();
-        }
-
-        /// <summary>
-        /// Queue a work item
-        /// </summary>
-        /// <param name="callback">A callback to execute</param>
-        /// <param name="state">
-        /// The context object of the work item. Used for passing arguments to the work item. 
-        /// </param>
-        /// <returns>Returns a work item result</returns>
-        public IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state)
-        {
-            WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state);
-            Enqueue(workItem);
-            return workItem.GetWorkItemResult();
-        }
-
-        /// <summary>
-        /// Queue a work item
-        /// </summary>
-        /// <param name="callback">A callback to execute</param>
-        /// <param name="state">
-        /// The context object of the work item. Used for passing arguments to the work item. 
-        /// </param>
-        /// <param name="workItemPriority">The work item priority</param>
-        /// <returns>Returns a work item result</returns>
-        public IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, WorkItemPriority workItemPriority)
-        {
-            PreQueueWorkItem();
-            WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, workItemPriority);
-            Enqueue(workItem);
-            return workItem.GetWorkItemResult();
-        }
-
-        /// <summary>
-        /// Queue a work item
-        /// </summary>
-        /// <param name="workItemInfo">Work item information</param>
-        /// <param name="callback">A callback to execute</param>
-        /// <param name="state">
-        /// The context object of the work item. Used for passing arguments to the work item. 
-        /// </param>
-        /// <returns>Returns a work item result</returns>
-        public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state)
-        {
-            PreQueueWorkItem();
-            WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback, state);
-            Enqueue(workItem);
-            return workItem.GetWorkItemResult();
-        }
-
-        /// <summary>
-        /// Queue a work item
-        /// </summary>
-        /// <param name="callback">A callback to execute</param>
-        /// <param name="state">
-        /// The context object of the work item. Used for passing arguments to the work item. 
-        /// </param>
-        /// <param name="postExecuteWorkItemCallback">
-        /// A delegate to call after the callback completion
-        /// </param>
-        /// <returns>Returns a work item result</returns>
-        public IWorkItemResult QueueWorkItem(
-            WorkItemCallback callback,
-            object state,
-            PostExecuteWorkItemCallback postExecuteWorkItemCallback)
-        {
-            PreQueueWorkItem();
-            WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback);
-            Enqueue(workItem);
-            return workItem.GetWorkItemResult();
-        }
-
-        /// <summary>
-        /// Queue a work item
-        /// </summary>
-        /// <param name="callback">A callback to execute</param>
-        /// <param name="state">
-        /// The context object of the work item. Used for passing arguments to the work item. 
-        /// </param>
-        /// <param name="postExecuteWorkItemCallback">
-        /// A delegate to call after the callback completion
-        /// </param>
-        /// <param name="workItemPriority">The work item priority</param>
-        /// <returns>Returns a work item result</returns>
-        public IWorkItemResult QueueWorkItem(
-            WorkItemCallback callback,
-            object state,
-            PostExecuteWorkItemCallback postExecuteWorkItemCallback,
-            WorkItemPriority workItemPriority)
-        {
-            PreQueueWorkItem();
-            WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, workItemPriority);
-            Enqueue(workItem);
-            return workItem.GetWorkItemResult();
-        }
-
-        /// <summary>
-        /// Queue a work item
-        /// </summary>
-        /// <param name="callback">A callback to execute</param>
-        /// <param name="state">
-        /// The context object of the work item. Used for passing arguments to the work item. 
-        /// </param>
-        /// <param name="postExecuteWorkItemCallback">
-        /// A delegate to call after the callback completion
-        /// </param>
-        /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
-        /// <returns>Returns a work item result</returns>
-        public IWorkItemResult QueueWorkItem(
-            WorkItemCallback callback,
-            object state,
-            PostExecuteWorkItemCallback postExecuteWorkItemCallback,
-            CallToPostExecute callToPostExecute)
-        {
-            PreQueueWorkItem();
-            WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute);
-            Enqueue(workItem);
-            return workItem.GetWorkItemResult();
-        }
-
-        /// <summary>
-        /// Queue a work item
-        /// </summary>
-        /// <param name="callback">A callback to execute</param>
-        /// <param name="state">
-        /// The context object of the work item. Used for passing arguments to the work item. 
-        /// </param>
-        /// <param name="postExecuteWorkItemCallback">
-        /// A delegate to call after the callback completion
-        /// </param>
-        /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
-        /// <param name="workItemPriority">The work item priority</param>
-        /// <returns>Returns a work item result</returns>
-        public IWorkItemResult QueueWorkItem(
-            WorkItemCallback callback,
-            object state,
-            PostExecuteWorkItemCallback postExecuteWorkItemCallback,
-            CallToPostExecute callToPostExecute,
-            WorkItemPriority workItemPriority)
-        {
-            PreQueueWorkItem();
-            WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute, workItemPriority);
-            Enqueue(workItem);
-            return workItem.GetWorkItemResult();
-        }
-
-        #endregion
-
-        #region QueueWorkItem(Action<...>)
-
-        public IWorkItemResult QueueWorkItem(Action action)
-        {
-            return QueueWorkItem (action, SmartThreadPool.DefaultWorkItemPriority);
-        }
-
-        public IWorkItemResult QueueWorkItem (Action action, WorkItemPriority priority)
-        {
-            PreQueueWorkItem ();
-            WorkItem workItem = WorkItemFactory.CreateWorkItem (
-                this,
-                WIGStartInfo,
-                delegate
-                {
-                    action.Invoke ();
-                    return null;
-                }, priority);
-            Enqueue (workItem);
-            return workItem.GetWorkItemResult ();
-        }
-
-        public IWorkItemResult QueueWorkItem<T>(Action<T> action, T arg)
-        {
-            return QueueWorkItem<T> (action, arg, SmartThreadPool.DefaultWorkItemPriority);
-        }
-
-        public IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg, WorkItemPriority priority)
-        {
-            PreQueueWorkItem ();
-            WorkItem workItem = WorkItemFactory.CreateWorkItem (
-                this,
-                WIGStartInfo,
-                state =>
-                {
-                    action.Invoke (arg);
-                    return null;
-                },
-                WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null, priority);
-            Enqueue (workItem);
-            return workItem.GetWorkItemResult ();
-        }
-
-        public IWorkItemResult QueueWorkItem<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2)
-        {
-            return QueueWorkItem<T1, T2> (action, arg1, arg2, SmartThreadPool.DefaultWorkItemPriority);
-        }
-
-        public IWorkItemResult QueueWorkItem<T1, T2> (Action<T1, T2> action, T1 arg1, T2 arg2, WorkItemPriority priority)
-        {
-            PreQueueWorkItem ();
-            WorkItem workItem = WorkItemFactory.CreateWorkItem (
-                this,
-                WIGStartInfo,
-                state =>
-                {
-                    action.Invoke (arg1, arg2);
-                    return null;
-                },
-                WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null, priority);
-            Enqueue (workItem);
-            return workItem.GetWorkItemResult ();
-        }
-
-        public IWorkItemResult QueueWorkItem<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3)
-        {
-            return QueueWorkItem<T1, T2, T3> (action, arg1, arg2, arg3, SmartThreadPool.DefaultWorkItemPriority);
-            ;
-        }
-
-        public IWorkItemResult QueueWorkItem<T1, T2, T3> (Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3, WorkItemPriority priority)
-        {
-            PreQueueWorkItem ();
-            WorkItem workItem = WorkItemFactory.CreateWorkItem (
-                this,
-                WIGStartInfo,
-                state =>
-                {
-                    action.Invoke (arg1, arg2, arg3);
-                    return null;
-                },
-                WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null, priority);
-            Enqueue (workItem);
-            return workItem.GetWorkItemResult ();
-        }
-
-        public IWorkItemResult QueueWorkItem<T1, T2, T3, T4>(
-            Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
-        {
-            return QueueWorkItem<T1, T2, T3, T4> (action, arg1, arg2, arg3, arg4,
-                                                  SmartThreadPool.DefaultWorkItemPriority);
-        }
-
-        public IWorkItemResult QueueWorkItem<T1, T2, T3, T4> (
-            Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, WorkItemPriority priority)
-        {
-            PreQueueWorkItem ();
-            WorkItem workItem = WorkItemFactory.CreateWorkItem (
-                           this,
-                           WIGStartInfo,
-                           state =>
-                           {
-                               action.Invoke (arg1, arg2, arg3, arg4);
-                               return null;
-                           },
-                           WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null, priority);
-            Enqueue (workItem);
-            return workItem.GetWorkItemResult ();
-        }
-
-        #endregion
-
-        #region QueueWorkItem(Func<...>)
-
-        public IWorkItemResult<TResult> QueueWorkItem<TResult>(Func<TResult> func)
-        {
-            PreQueueWorkItem();
-            WorkItem workItem = WorkItemFactory.CreateWorkItem(
-                            this,
-                            WIGStartInfo,
-                            state =>
-                            {
-                                return func.Invoke();
-                            });
-            Enqueue(workItem);
-            return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
-        }
-
-        public IWorkItemResult<TResult> QueueWorkItem<T, TResult>(Func<T, TResult> func, T arg)
-        {
-            PreQueueWorkItem();
-            WorkItem workItem = WorkItemFactory.CreateWorkItem(
-                this,
-                WIGStartInfo,
-                state =>
-                {
-                    return func.Invoke(arg);
-                },
-                WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null);
-            Enqueue(workItem);
-            return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
-        }
-
-        public IWorkItemResult<TResult> QueueWorkItem<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 arg1, T2 arg2)
-        {
-            PreQueueWorkItem();
-            WorkItem workItem = WorkItemFactory.CreateWorkItem(
-                            this,
-                            WIGStartInfo,
-                            state =>
-                            {
-                                return func.Invoke(arg1, arg2);
-                            },
-                           WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null);
-            Enqueue(workItem);
-            return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
-        }
-
-        public IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, TResult>(
-            Func<T1, T2, T3, TResult> func, T1 arg1, T2 arg2, T3 arg3)
-        {
-            PreQueueWorkItem();
-            WorkItem workItem = WorkItemFactory.CreateWorkItem(
-                            this,
-                            WIGStartInfo,
-                            state =>
-                            {
-                                return func.Invoke(arg1, arg2, arg3);
-                            },
-                           WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null);
-            Enqueue(workItem);
-            return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
-        }
-
-        public IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, T4, TResult>(
-            Func<T1, T2, T3, T4, TResult> func, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
-        {
-            PreQueueWorkItem();
-            WorkItem workItem = WorkItemFactory.CreateWorkItem(
-                            this,
-                            WIGStartInfo,
-                            state =>
-                            {
-                                return func.Invoke(arg1, arg2, arg3, arg4);
-                            },
-                           WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null);
-            Enqueue(workItem);
-            return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
-        }
-
-        #endregion
-
-        #endregion
-    }
+using System;
+using System.Threading;
+
+namespace Amib.Threading.Internal
+{
+    public abstract class WorkItemsGroupBase : IWorkItemsGroup
+    {
+        #region Private Fields
+
+        /// <summary>
+        /// Contains the name of this instance of SmartThreadPool.
+        /// Can be changed by the user.
+        /// </summary>
+        private string _name = "WorkItemsGroupBase";
+
+        public WorkItemsGroupBase()
+        {
+            IsIdle = true;
+        }
+
+        #endregion
+
+        #region IWorkItemsGroup Members
+
+        #region Public Methods
+
+        /// <summary>
+        /// Get/Set the name of the SmartThreadPool/WorkItemsGroup instance
+        /// </summary>
+        public string Name
+        {
+            get { return _name; }
+            set { _name = value; }
+        }
+
+        #endregion
+
+        #region Abstract Methods
+
+        public abstract int Concurrency { get; set; }
+        public abstract int WaitingCallbacks { get; }
+        public abstract object[] GetStates();
+        public abstract WIGStartInfo WIGStartInfo { get; }
+        public abstract void Start();
+        public abstract void Cancel(bool abortExecution);
+        public abstract bool WaitForIdle(int millisecondsTimeout);
+        public abstract event WorkItemsGroupIdleHandler OnIdle;
+
+        internal abstract void Enqueue(WorkItem workItem);
+        internal virtual void PreQueueWorkItem() { }
+
+        #endregion
+
+        #region Common Base Methods
+
+        /// <summary>
+        /// Cancel all the work items.
+        /// Same as Cancel(false)
+        /// </summary>
+        public virtual void Cancel()
+        {
+            Cancel(false);
+        }
+
+        /// <summary>
+        /// Wait for the SmartThreadPool/WorkItemsGroup to be idle
+        /// </summary>
+        public void WaitForIdle()
+        {
+            WaitForIdle(Timeout.Infinite);
+        }
+
+        /// <summary>
+        /// Wait for the SmartThreadPool/WorkItemsGroup to be idle
+        /// </summary>
+        public bool WaitForIdle(TimeSpan timeout)
+        {
+            return WaitForIdle((int)timeout.TotalMilliseconds);
+        }
+
+        /// <summary>
+        /// IsIdle is true when there are no work items running or queued.
+        /// </summary>
+        public bool IsIdle { get; protected set; }
+
+        #endregion
+
+        #region QueueWorkItem
+
+        /// <summary>
+        /// Queue a work item
+        /// </summary>
+        /// <param name="callback">A callback to execute</param>
+        /// <returns>Returns a work item result</returns>
+        public IWorkItemResult QueueWorkItem(WorkItemCallback callback)
+        {
+            WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback);
+            Enqueue(workItem);
+            return workItem.GetWorkItemResult();
+        }
+
+        /// <summary>
+        /// Queue a work item
+        /// </summary>
+        /// <param name="callback">A callback to execute</param>
+        /// <param name="workItemPriority">The priority of the work item</param>
+        /// <returns>Returns a work item result</returns>
+        public IWorkItemResult QueueWorkItem(WorkItemCallback callback, WorkItemPriority workItemPriority)
+        {
+            PreQueueWorkItem();
+            WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, workItemPriority);
+            Enqueue(workItem);
+            return workItem.GetWorkItemResult();
+        }
+
+        /// <summary>
+        /// Queue a work item
+        /// </summary>
+        /// <param name="workItemInfo">Work item info</param>
+        /// <param name="callback">A callback to execute</param>
+        /// <returns>Returns a work item result</returns>
+        public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback)
+        {
+            PreQueueWorkItem();
+            WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback);
+            Enqueue(workItem);
+            return workItem.GetWorkItemResult();
+        }
+
+        /// <summary>
+        /// Queue a work item
+        /// </summary>
+        /// <param name="callback">A callback to execute</param>
+        /// <param name="state">
+        /// The context object of the work item. Used for passing arguments to the work item. 
+        /// </param>
+        /// <returns>Returns a work item result</returns>
+        public IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state)
+        {
+            WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state);
+            Enqueue(workItem);
+            return workItem.GetWorkItemResult();
+        }
+
+        /// <summary>
+        /// Queue a work item
+        /// </summary>
+        /// <param name="callback">A callback to execute</param>
+        /// <param name="state">
+        /// The context object of the work item. Used for passing arguments to the work item. 
+        /// </param>
+        /// <param name="workItemPriority">The work item priority</param>
+        /// <returns>Returns a work item result</returns>
+        public IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, WorkItemPriority workItemPriority)
+        {
+            PreQueueWorkItem();
+            WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, workItemPriority);
+            Enqueue(workItem);
+            return workItem.GetWorkItemResult();
+        }
+
+        /// <summary>
+        /// Queue a work item
+        /// </summary>
+        /// <param name="workItemInfo">Work item information</param>
+        /// <param name="callback">A callback to execute</param>
+        /// <param name="state">
+        /// The context object of the work item. Used for passing arguments to the work item. 
+        /// </param>
+        /// <returns>Returns a work item result</returns>
+        public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state)
+        {
+            PreQueueWorkItem();
+            WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback, state);
+            Enqueue(workItem);
+            return workItem.GetWorkItemResult();
+        }
+
+        /// <summary>
+        /// Queue a work item
+        /// </summary>
+        /// <param name="callback">A callback to execute</param>
+        /// <param name="state">
+        /// The context object of the work item. Used for passing arguments to the work item. 
+        /// </param>
+        /// <param name="postExecuteWorkItemCallback">
+        /// A delegate to call after the callback completion
+        /// </param>
+        /// <returns>Returns a work item result</returns>
+        public IWorkItemResult QueueWorkItem(
+            WorkItemCallback callback,
+            object state,
+            PostExecuteWorkItemCallback postExecuteWorkItemCallback)
+        {
+            PreQueueWorkItem();
+            WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback);
+            Enqueue(workItem);
+            return workItem.GetWorkItemResult();
+        }
+
+        /// <summary>
+        /// Queue a work item
+        /// </summary>
+        /// <param name="callback">A callback to execute</param>
+        /// <param name="state">
+        /// The context object of the work item. Used for passing arguments to the work item. 
+        /// </param>
+        /// <param name="postExecuteWorkItemCallback">
+        /// A delegate to call after the callback completion
+        /// </param>
+        /// <param name="workItemPriority">The work item priority</param>
+        /// <returns>Returns a work item result</returns>
+        public IWorkItemResult QueueWorkItem(
+            WorkItemCallback callback,
+            object state,
+            PostExecuteWorkItemCallback postExecuteWorkItemCallback,
+            WorkItemPriority workItemPriority)
+        {
+            PreQueueWorkItem();
+            WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, workItemPriority);
+            Enqueue(workItem);
+            return workItem.GetWorkItemResult();
+        }
+
+        /// <summary>
+        /// Queue a work item
+        /// </summary>
+        /// <param name="callback">A callback to execute</param>
+        /// <param name="state">
+        /// The context object of the work item. Used for passing arguments to the work item. 
+        /// </param>
+        /// <param name="postExecuteWorkItemCallback">
+        /// A delegate to call after the callback completion
+        /// </param>
+        /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
+        /// <returns>Returns a work item result</returns>
+        public IWorkItemResult QueueWorkItem(
+            WorkItemCallback callback,
+            object state,
+            PostExecuteWorkItemCallback postExecuteWorkItemCallback,
+            CallToPostExecute callToPostExecute)
+        {
+            PreQueueWorkItem();
+            WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute);
+            Enqueue(workItem);
+            return workItem.GetWorkItemResult();
+        }
+
+        /// <summary>
+        /// Queue a work item
+        /// </summary>
+        /// <param name="callback">A callback to execute</param>
+        /// <param name="state">
+        /// The context object of the work item. Used for passing arguments to the work item. 
+        /// </param>
+        /// <param name="postExecuteWorkItemCallback">
+        /// A delegate to call after the callback completion
+        /// </param>
+        /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
+        /// <param name="workItemPriority">The work item priority</param>
+        /// <returns>Returns a work item result</returns>
+        public IWorkItemResult QueueWorkItem(
+            WorkItemCallback callback,
+            object state,
+            PostExecuteWorkItemCallback postExecuteWorkItemCallback,
+            CallToPostExecute callToPostExecute,
+            WorkItemPriority workItemPriority)
+        {
+            PreQueueWorkItem();
+            WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute, workItemPriority);
+            Enqueue(workItem);
+            return workItem.GetWorkItemResult();
+        }
+
+        #endregion
+
+        #region QueueWorkItem(Action<...>)
+
+        public IWorkItemResult QueueWorkItem(Action action)
+        {
+            return QueueWorkItem (action, SmartThreadPool.DefaultWorkItemPriority);
+        }
+
+        public IWorkItemResult QueueWorkItem (Action action, WorkItemPriority priority)
+        {
+            PreQueueWorkItem ();
+            WorkItem workItem = WorkItemFactory.CreateWorkItem (
+                this,
+                WIGStartInfo,
+                delegate
+                {
+                    action.Invoke ();
+                    return null;
+                }, priority);
+            Enqueue (workItem);
+            return workItem.GetWorkItemResult ();
+        }
+
+        public IWorkItemResult QueueWorkItem<T>(Action<T> action, T arg)
+        {
+            return QueueWorkItem<T> (action, arg, SmartThreadPool.DefaultWorkItemPriority);
+        }
+
+        public IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg, WorkItemPriority priority)
+        {
+            PreQueueWorkItem ();
+            WorkItem workItem = WorkItemFactory.CreateWorkItem (
+                this,
+                WIGStartInfo,
+                state =>
+                {
+                    action.Invoke (arg);
+                    return null;
+                },
+                WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null, priority);
+            Enqueue (workItem);
+            return workItem.GetWorkItemResult ();
+        }
+
+        public IWorkItemResult QueueWorkItem<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2)
+        {
+            return QueueWorkItem<T1, T2> (action, arg1, arg2, SmartThreadPool.DefaultWorkItemPriority);
+        }
+
+        public IWorkItemResult QueueWorkItem<T1, T2> (Action<T1, T2> action, T1 arg1, T2 arg2, WorkItemPriority priority)
+        {
+            PreQueueWorkItem ();
+            WorkItem workItem = WorkItemFactory.CreateWorkItem (
+                this,
+                WIGStartInfo,
+                state =>
+                {
+                    action.Invoke (arg1, arg2);
+                    return null;
+                },
+                WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null, priority);
+            Enqueue (workItem);
+            return workItem.GetWorkItemResult ();
+        }
+
+        public IWorkItemResult QueueWorkItem<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3)
+        {
+            return QueueWorkItem<T1, T2, T3> (action, arg1, arg2, arg3, SmartThreadPool.DefaultWorkItemPriority);
+            ;
+        }
+
+        public IWorkItemResult QueueWorkItem<T1, T2, T3> (Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3, WorkItemPriority priority)
+        {
+            PreQueueWorkItem ();
+            WorkItem workItem = WorkItemFactory.CreateWorkItem (
+                this,
+                WIGStartInfo,
+                state =>
+                {
+                    action.Invoke (arg1, arg2, arg3);
+                    return null;
+                },
+                WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null, priority);
+            Enqueue (workItem);
+            return workItem.GetWorkItemResult ();
+        }
+
+        public IWorkItemResult QueueWorkItem<T1, T2, T3, T4>(
+            Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
+        {
+            return QueueWorkItem<T1, T2, T3, T4> (action, arg1, arg2, arg3, arg4,
+                                                  SmartThreadPool.DefaultWorkItemPriority);
+        }
+
+        public IWorkItemResult QueueWorkItem<T1, T2, T3, T4> (
+            Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, WorkItemPriority priority)
+        {
+            PreQueueWorkItem ();
+            WorkItem workItem = WorkItemFactory.CreateWorkItem (
+                           this,
+                           WIGStartInfo,
+                           state =>
+                           {
+                               action.Invoke (arg1, arg2, arg3, arg4);
+                               return null;
+                           },
+                           WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null, priority);
+            Enqueue (workItem);
+            return workItem.GetWorkItemResult ();
+        }
+
+        #endregion
+
+        #region QueueWorkItem(Func<...>)
+
+        public IWorkItemResult<TResult> QueueWorkItem<TResult>(Func<TResult> func)
+        {
+            PreQueueWorkItem();
+            WorkItem workItem = WorkItemFactory.CreateWorkItem(
+                            this,
+                            WIGStartInfo,
+                            state =>
+                            {
+                                return func.Invoke();
+                            });
+            Enqueue(workItem);
+            return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
+        }
+
+        public IWorkItemResult<TResult> QueueWorkItem<T, TResult>(Func<T, TResult> func, T arg)
+        {
+            PreQueueWorkItem();
+            WorkItem workItem = WorkItemFactory.CreateWorkItem(
+                this,
+                WIGStartInfo,
+                state =>
+                {
+                    return func.Invoke(arg);
+                },
+                WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null);
+            Enqueue(workItem);
+            return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
+        }
+
+        public IWorkItemResult<TResult> QueueWorkItem<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 arg1, T2 arg2)
+        {
+            PreQueueWorkItem();
+            WorkItem workItem = WorkItemFactory.CreateWorkItem(
+                            this,
+                            WIGStartInfo,
+                            state =>
+                            {
+                                return func.Invoke(arg1, arg2);
+                            },
+                           WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null);
+            Enqueue(workItem);
+            return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
+        }
+
+        public IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, TResult>(
+            Func<T1, T2, T3, TResult> func, T1 arg1, T2 arg2, T3 arg3)
+        {
+            PreQueueWorkItem();
+            WorkItem workItem = WorkItemFactory.CreateWorkItem(
+                            this,
+                            WIGStartInfo,
+                            state =>
+                            {
+                                return func.Invoke(arg1, arg2, arg3);
+                            },
+                           WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null);
+            Enqueue(workItem);
+            return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
+        }
+
+        public IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, T4, TResult>(
+            Func<T1, T2, T3, T4, TResult> func, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
+        {
+            PreQueueWorkItem();
+            WorkItem workItem = WorkItemFactory.CreateWorkItem(
+                            this,
+                            WIGStartInfo,
+                            state =>
+                            {
+                                return func.Invoke(arg1, arg2, arg3, arg4);
+                            },
+                           WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null);
+            Enqueue(workItem);
+            return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
+        }
+
+        #endregion
+
+        #endregion
+    }
 }

+ 645 - 645
ThirdParty/SmartThreadPool/WorkItemsQueue.cs

@@ -1,645 +1,645 @@
-using System;
-using System.Collections.Generic;
-using System.Threading;
-
-namespace Amib.Threading.Internal
-{
-	#region WorkItemsQueue class
-
-	/// <summary>
-	/// WorkItemsQueue class.
-	/// </summary>
-	public class WorkItemsQueue : IDisposable
-	{
-		#region Member variables
-
-		/// <summary>
-		/// Waiters queue (implemented as stack).
-		/// </summary>
-		private readonly WaiterEntry _headWaiterEntry = new WaiterEntry();
-
-		/// <summary>
-		/// Waiters count
-		/// </summary>
-		private int _waitersCount = 0;
-
-		/// <summary>
-		/// Work items queue
-		/// </summary>
-		private readonly PriorityQueue _workItems = new PriorityQueue();
-
-        /// <summary>
-        /// Indicate that work items are allowed to be queued
-        /// </summary>
-        private bool _isWorkItemsQueueActive = true;
-
-
-#if (WINDOWS_PHONE) 
-        private static readonly Dictionary<int, WaiterEntry> _waiterEntries = new Dictionary<int, WaiterEntry>();
-#elif (_WINDOWS_CE)
-        private static LocalDataStoreSlot _waiterEntrySlot = Thread.AllocateDataSlot();
-#else
-
-        [ThreadStatic]
-        private static WaiterEntry _waiterEntry;
-#endif
-
-
-        /// <summary>
-        /// Each thread in the thread pool keeps its own waiter entry.
-        /// </summary>
-        private static WaiterEntry CurrentWaiterEntry
-        {
-#if (WINDOWS_PHONE) 
-            get
-            {
-                lock (_waiterEntries)
-                {
-                    WaiterEntry waiterEntry;
-                    if (_waiterEntries.TryGetValue(Thread.CurrentThread.ManagedThreadId, out waiterEntry))
-                    {
-                        return waiterEntry;
-                    }
-                }
-                return null;
-            }
-            set
-            {
-                lock (_waiterEntries)
-                {
-                    _waiterEntries[Thread.CurrentThread.ManagedThreadId] = value;
-                }
-            }
-#elif (_WINDOWS_CE)
-            get
-            {
-                return Thread.GetData(_waiterEntrySlot) as WaiterEntry;
-            }
-            set
-            {
-                Thread.SetData(_waiterEntrySlot, value);
-            }
-#else
-            get
-            {
-                return _waiterEntry;
-            }
-            set
-            {
-                _waiterEntry = value;
-            }
-#endif
-        }
-
-        /// <summary>
-		/// A flag that indicates if the WorkItemsQueue has been disposed.
-		/// </summary>
-        private bool _isDisposed = false;
-
-		#endregion
-
-		#region Public properties
-
-        /// <summary>
-        /// Returns the current number of work items in the queue
-        /// </summary>
-		public int Count
-		{
-			get
-			{
-                return _workItems.Count;
-			}
-		}
-
-		/// <summary>
-		/// Returns the current number of waiters
-		/// </summary>
-		public int WaitersCount
-		{
-			get
-			{
-				return _waitersCount;
-			}
-		}
-
-
-        #endregion
-
-        #region Public methods
-
-		/// <summary>
-		/// Enqueue a work item to the queue.
-		/// </summary>
-		public bool EnqueueWorkItem(WorkItem workItem)
-		{
-			// A work item cannot be null, since null is used in the
-			// WaitForWorkItem() method to indicate timeout or cancel
-			if (null == workItem)
-			{
-				throw new ArgumentNullException("workItem" , "workItem cannot be null");
-			}
-
-			bool enqueue = true;
-
-			// First check if there is a waiter waiting for work item. During 
-			// the check, timed out waiters are ignored. If there is no 
-			// waiter then the work item is queued.
-			lock(this)
-			{
-                ValidateNotDisposed();
-
-                if (!_isWorkItemsQueueActive)
-                {
-                    return false;
-                }
-
-				while(_waitersCount > 0)
-				{
-					// Dequeue a waiter.
-					WaiterEntry waiterEntry = PopWaiter();
-
-					// Signal the waiter. On success break the loop
-					if (waiterEntry.Signal(workItem))
-					{
-						enqueue = false;
-						break;
-					}
-				}
-
-				if (enqueue)
-				{
-					// Enqueue the work item
-					_workItems.Enqueue(workItem);
-				}
-			}
-            return true;
-		}
-
-
-		/// <summary>
-		/// Waits for a work item or exits on timeout or cancel
-		/// </summary>
-		/// <param name="millisecondsTimeout">Timeout in milliseconds</param>
-		/// <param name="cancelEvent">Cancel wait handle</param>
-		/// <returns>Returns true if the resource was granted</returns>
-		public WorkItem DequeueWorkItem(
-			int millisecondsTimeout, 
-			WaitHandle cancelEvent)
-		{
-			// This method cause the caller to wait for a work item.
-			// If there is at least one waiting work item then the 
-			// method returns immidiately with it.
-			// 
-			// If there are no waiting work items then the caller 
-			// is queued between other waiters for a work item to arrive.
-			// 
-			// If a work item didn't come within millisecondsTimeout or 
-			// the user canceled the wait by signaling the cancelEvent 
-			// then the method returns null to indicate that the caller 
-			// didn't get a work item.
-
-			WaiterEntry waiterEntry;
-			WorkItem workItem = null;
-		    lock (this)
-		    {
-                ValidateNotDisposed();
-
-                // If there are waiting work items then take one and return.
-                if (_workItems.Count > 0)
-                {
-                    workItem = _workItems.Dequeue() as WorkItem;
-                    return workItem;
-                }
-
-                // No waiting work items ...
-
-                // Get the waiter entry for the waiters queue
-                waiterEntry = GetThreadWaiterEntry();
-
-                // Put the waiter with the other waiters
-                PushWaiter(waiterEntry);
-		    }
-
-		    // Prepare array of wait handle for the WaitHandle.WaitAny()
-            WaitHandle [] waitHandles = new WaitHandle[] { 
-																waiterEntry.WaitHandle, 
-																cancelEvent };
-
-			// Wait for an available resource, cancel event, or timeout.
-
-			// During the wait we are supposes to exit the synchronization 
-			// domain. (Placing true as the third argument of the WaitAny())
-			// It just doesn't work, I don't know why, so I have two lock(this) 
-			// statments instead of one.
-
-            int index = STPEventWaitHandle.WaitAny(
-				waitHandles,
-				millisecondsTimeout, 
-				true);
-
-			lock(this)
-			{
-				// success is true if it got a work item.
-				bool success = (0 == index);
-
-				// The timeout variable is used only for readability.
-				// (We treat cancel as timeout)
-				bool timeout = !success;
-
-				// On timeout update the waiterEntry that it is timed out
-				if (timeout)
-				{
-					// The Timeout() fails if the waiter has already been signaled
-					timeout = waiterEntry.Timeout();
-
-					// On timeout remove the waiter from the queue.
-					// Note that the complexity is O(1).
-					if(timeout)
-					{
-						RemoveWaiter(waiterEntry, false);
-					}
-
-					// Again readability
-					success = !timeout;
-				}
-
-				// On success return the work item
-				if (success)
-				{
-					workItem = waiterEntry.WorkItem;
-
-					if (null == workItem)
-					{
-						workItem = _workItems.Dequeue() as WorkItem;
-					}
-				}
-			}
-			// On failure return null.
-			return workItem;
-		}
-
-        /// <summary>
-        /// Cleanup the work items queue, hence no more work 
-        /// items are allowed to be queue
-        /// </summary>
-        private void Cleanup()
-        {
-            lock(this)
-            {
-                // Deactivate only once
-                if (!_isWorkItemsQueueActive)
-                {
-                    return;
-                }
-
-                // Don't queue more work items
-                _isWorkItemsQueueActive = false;
-
-                foreach(WorkItem workItem in _workItems)
-                {
-                    workItem.DisposeOfState();
-                }
-
-                // Clear the work items that are already queued
-                _workItems.Clear();
-
-                // Note: 
-                // I don't iterate over the queue and dispose of work items's states, 
-                // since if a work item has a state object that is still in use in the 
-                // application then I must not dispose it.
-
-                // Tell the waiters that they were timed out.
-                // It won't signal them to exit, but to ignore their
-                // next work item.
-				while(_waitersCount > 0)
-				{
-					WaiterEntry waiterEntry = PopWaiter();
-					waiterEntry.Timeout();
-				}
-            }
-        }
-
-        public object[] GetStates()
-        {
-            lock (this)
-            {
-                object[] states = new object[_workItems.Count];
-                int i = 0;
-                foreach (WorkItem workItem in _workItems)
-                {
-                    states[i] = workItem.GetWorkItemResult().State;
-                    ++i;
-                }
-                return states;
-            }
-        }
-
-		#endregion
-
-		#region Private methods
-
-		/// <summary>
-		/// Returns the WaiterEntry of the current thread
-		/// </summary>
-		/// <returns></returns>
-		/// In order to avoid creation and destuction of WaiterEntry
-		/// objects each thread has its own WaiterEntry object.
-		private static WaiterEntry GetThreadWaiterEntry()
-		{
-			if (null == CurrentWaiterEntry)
-			{
-				CurrentWaiterEntry = new WaiterEntry();
-			}
-			CurrentWaiterEntry.Reset();
-			return CurrentWaiterEntry;
-		}
-
-		#region Waiters stack methods
-
-		/// <summary>
-		/// Push a new waiter into the waiter's stack
-		/// </summary>
-		/// <param name="newWaiterEntry">A waiter to put in the stack</param>
-		public void PushWaiter(WaiterEntry newWaiterEntry)
-		{
-			// Remove the waiter if it is already in the stack and 
-			// update waiter's count as needed
-			RemoveWaiter(newWaiterEntry, false);
-
-			// If the stack is empty then newWaiterEntry is the new head of the stack 
-			if (null == _headWaiterEntry._nextWaiterEntry)
-			{
-				_headWaiterEntry._nextWaiterEntry = newWaiterEntry;
-				newWaiterEntry._prevWaiterEntry = _headWaiterEntry;
-
-			}
-			// If the stack is not empty then put newWaiterEntry as the new head 
-			// of the stack.
-			else
-			{
-				// Save the old first waiter entry
-				WaiterEntry oldFirstWaiterEntry = _headWaiterEntry._nextWaiterEntry;
-
-                // Update the links
-				_headWaiterEntry._nextWaiterEntry = newWaiterEntry;
-				newWaiterEntry._nextWaiterEntry = oldFirstWaiterEntry;
-				newWaiterEntry._prevWaiterEntry = _headWaiterEntry;
-				oldFirstWaiterEntry._prevWaiterEntry = newWaiterEntry;
-			}
-
-			// Increment the number of waiters
-			++_waitersCount;
-		}
-
-		/// <summary>
-		/// Pop a waiter from the waiter's stack
-		/// </summary>
-		/// <returns>Returns the first waiter in the stack</returns>
-		private WaiterEntry PopWaiter()
-		{
-			// Store the current stack head
-			WaiterEntry oldFirstWaiterEntry = _headWaiterEntry._nextWaiterEntry;
-
-			// Store the new stack head
-			WaiterEntry newHeadWaiterEntry = oldFirstWaiterEntry._nextWaiterEntry;
-
-			// Update the old stack head list links and decrement the number
-			// waiters.
-			RemoveWaiter(oldFirstWaiterEntry, true);
-
-			// Update the new stack head
-			_headWaiterEntry._nextWaiterEntry = newHeadWaiterEntry;
-			if (null != newHeadWaiterEntry)
-			{
-				newHeadWaiterEntry._prevWaiterEntry = _headWaiterEntry;
-			}
-
-			// Return the old stack head
-			return oldFirstWaiterEntry;
-		}
-
-		/// <summary>
-		/// Remove a waiter from the stack
-		/// </summary>
-		/// <param name="waiterEntry">A waiter entry to remove</param>
-		/// <param name="popDecrement">If true the waiter count is always decremented</param>
-		private void RemoveWaiter(WaiterEntry waiterEntry, bool popDecrement)
-		{
-			// Store the prev entry in the list
-			WaiterEntry prevWaiterEntry = waiterEntry._prevWaiterEntry;
-
-			// Store the next entry in the list
-			WaiterEntry nextWaiterEntry = waiterEntry._nextWaiterEntry;
-
-			// A flag to indicate if we need to decrement the waiters count.
-			// If we got here from PopWaiter then we must decrement.
-			// If we got here from PushWaiter then we decrement only if
-			// the waiter was already in the stack.
-			bool decrementCounter = popDecrement;
-
-			// Null the waiter's entry links
-			waiterEntry._prevWaiterEntry = null;
-			waiterEntry._nextWaiterEntry = null;
-
-			// If the waiter entry had a prev link then update it.
-			// It also means that the waiter is already in the list and we
-			// need to decrement the waiters count.
-			if (null != prevWaiterEntry)
-			{
-				prevWaiterEntry._nextWaiterEntry = nextWaiterEntry;
-				decrementCounter = true;
-			}
-
-			// If the waiter entry had a next link then update it.
-			// It also means that the waiter is already in the list and we
-			// need to decrement the waiters count.
-			if (null != nextWaiterEntry)
-			{
-				nextWaiterEntry._prevWaiterEntry = prevWaiterEntry;
-				decrementCounter = true;
-			}
-
-			// Decrement the waiters count if needed
-			if (decrementCounter)
-			{
-				--_waitersCount;
-			}
-		}
-
-		#endregion
-
-		#endregion
-
-		#region WaiterEntry class 
-
-		// A waiter entry in the _waiters queue.
-		public sealed class WaiterEntry : IDisposable
-		{
-			#region Member variables
-
-			/// <summary>
-			/// Event to signal the waiter that it got the work item.
-			/// </summary>
-			//private AutoResetEvent _waitHandle = new AutoResetEvent(false);
-            private AutoResetEvent _waitHandle = EventWaitHandleFactory.CreateAutoResetEvent();
-
-			/// <summary>
-			/// Flag to know if this waiter already quited from the queue 
-			/// because of a timeout.
-			/// </summary>
-			private bool _isTimedout = false;
-
-			/// <summary>
-			/// Flag to know if the waiter was signaled and got a work item. 
-			/// </summary>
-			private bool _isSignaled = false;
-
-            /// <summary>
-            /// A work item that passed directly to the waiter withou going 
-            /// through the queue
-            /// </summary>
-			private WorkItem _workItem = null;
-
-            private bool _isDisposed = false;
-
-			// Linked list members
-			internal WaiterEntry _nextWaiterEntry = null;
-			internal WaiterEntry _prevWaiterEntry = null;
-
-			#endregion
-
-			#region Construction
-
-			public WaiterEntry()
-			{
-				Reset();
-			}
-						
-			#endregion
-
-			#region Public methods
-
-			public WaitHandle WaitHandle
-			{
-				get { return _waitHandle; }
-			}
-
-			public WorkItem WorkItem
-			{
-				get
-				{
-					return _workItem;
-				}
-			}
-
-			/// <summary>
-			/// Signal the waiter that it got a work item.
-			/// </summary>
-			/// <returns>Return true on success</returns>
-			/// The method fails if Timeout() preceded its call
-			public bool Signal(WorkItem workItem)
-			{
-				lock(this)
-				{
-					if (!_isTimedout)
-					{
-						_workItem = workItem;
-						_isSignaled = true;
-						_waitHandle.Set();
-						return true;
-					}
-				}
-				return false;
-			}
-
-			/// <summary>
-			/// Mark the wait entry that it has been timed out
-			/// </summary>
-			/// <returns>Return true on success</returns>
-			/// The method fails if Signal() preceded its call
-			public bool Timeout()
-			{
-				lock(this)
-				{
-					// Time out can happen only if the waiter wasn't marked as
-					// signaled
-					if (!_isSignaled)
-					{
-						// We don't remove the waiter from the queue, the DequeueWorkItem 
-                        // method skips _waiters that were timed out.
-						_isTimedout = true;
-						return true;
-					}
-				}
-				return false;
-			}
-
-			/// <summary>
-			/// Reset the wait entry so it can be used again
-			/// </summary>
-			public void Reset()
-			{
-				_workItem = null;
-				_isTimedout = false;
-				_isSignaled = false;
-				_waitHandle.Reset();
-			}
-
-			/// <summary>
-			/// Free resources
-			/// </summary>
-			public void Close()
-			{
-				if (null != _waitHandle)
-				{
-					_waitHandle.Close();
-					_waitHandle = null;
-				}
-			}
-
-			#endregion
-
-			#region IDisposable Members
-
-			public void Dispose()
-			{
-                lock (this)
-                {
-                    if (!_isDisposed)
-                    {
-                        Close();
-                    }
-                    _isDisposed = true;
-                }
-            }
-
-			#endregion
-		}
-
-		#endregion
-
-        #region IDisposable Members
-
-        public void Dispose()
-        {
-            if (!_isDisposed)
-            {
-                Cleanup();
-            }
-            _isDisposed = true;
-        }
-
-        private void ValidateNotDisposed()
-        {
-            if(_isDisposed)
-            {
-                throw new ObjectDisposedException(GetType().ToString(), "The SmartThreadPool has been shutdown");
-            }
-        }
-
-        #endregion
-    }
-
-	#endregion
-}
-
+using System;
+using System.Collections.Generic;
+using System.Threading;
+
+namespace Amib.Threading.Internal
+{
+	#region WorkItemsQueue class
+
+	/// <summary>
+	/// WorkItemsQueue class.
+	/// </summary>
+	public class WorkItemsQueue : IDisposable
+	{
+		#region Member variables
+
+		/// <summary>
+		/// Waiters queue (implemented as stack).
+		/// </summary>
+		private readonly WaiterEntry _headWaiterEntry = new WaiterEntry();
+
+		/// <summary>
+		/// Waiters count
+		/// </summary>
+		private int _waitersCount = 0;
+
+		/// <summary>
+		/// Work items queue
+		/// </summary>
+		private readonly PriorityQueue _workItems = new PriorityQueue();
+
+        /// <summary>
+        /// Indicate that work items are allowed to be queued
+        /// </summary>
+        private bool _isWorkItemsQueueActive = true;
+
+
+#if (WINDOWS_PHONE) 
+        private static readonly Dictionary<int, WaiterEntry> _waiterEntries = new Dictionary<int, WaiterEntry>();
+#elif (_WINDOWS_CE)
+        private static LocalDataStoreSlot _waiterEntrySlot = Thread.AllocateDataSlot();
+#else
+
+        [ThreadStatic]
+        private static WaiterEntry _waiterEntry;
+#endif
+
+
+        /// <summary>
+        /// Each thread in the thread pool keeps its own waiter entry.
+        /// </summary>
+        private static WaiterEntry CurrentWaiterEntry
+        {
+#if (WINDOWS_PHONE) 
+            get
+            {
+                lock (_waiterEntries)
+                {
+                    WaiterEntry waiterEntry;
+                    if (_waiterEntries.TryGetValue(Thread.CurrentThread.ManagedThreadId, out waiterEntry))
+                    {
+                        return waiterEntry;
+                    }
+                }
+                return null;
+            }
+            set
+            {
+                lock (_waiterEntries)
+                {
+                    _waiterEntries[Thread.CurrentThread.ManagedThreadId] = value;
+                }
+            }
+#elif (_WINDOWS_CE)
+            get
+            {
+                return Thread.GetData(_waiterEntrySlot) as WaiterEntry;
+            }
+            set
+            {
+                Thread.SetData(_waiterEntrySlot, value);
+            }
+#else
+            get
+            {
+                return _waiterEntry;
+            }
+            set
+            {
+                _waiterEntry = value;
+            }
+#endif
+        }
+
+        /// <summary>
+		/// A flag that indicates if the WorkItemsQueue has been disposed.
+		/// </summary>
+        private bool _isDisposed = false;
+
+		#endregion
+
+		#region Public properties
+
+        /// <summary>
+        /// Returns the current number of work items in the queue
+        /// </summary>
+		public int Count
+		{
+			get
+			{
+                return _workItems.Count;
+			}
+		}
+
+		/// <summary>
+		/// Returns the current number of waiters
+		/// </summary>
+		public int WaitersCount
+		{
+			get
+			{
+				return _waitersCount;
+			}
+		}
+
+
+        #endregion
+
+        #region Public methods
+
+		/// <summary>
+		/// Enqueue a work item to the queue.
+		/// </summary>
+		public bool EnqueueWorkItem(WorkItem workItem)
+		{
+			// A work item cannot be null, since null is used in the
+			// WaitForWorkItem() method to indicate timeout or cancel
+			if (null == workItem)
+			{
+				throw new ArgumentNullException("workItem" , "workItem cannot be null");
+			}
+
+			bool enqueue = true;
+
+			// First check if there is a waiter waiting for work item. During 
+			// the check, timed out waiters are ignored. If there is no 
+			// waiter then the work item is queued.
+			lock(this)
+			{
+                ValidateNotDisposed();
+
+                if (!_isWorkItemsQueueActive)
+                {
+                    return false;
+                }
+
+				while(_waitersCount > 0)
+				{
+					// Dequeue a waiter.
+					WaiterEntry waiterEntry = PopWaiter();
+
+					// Signal the waiter. On success break the loop
+					if (waiterEntry.Signal(workItem))
+					{
+						enqueue = false;
+						break;
+					}
+				}
+
+				if (enqueue)
+				{
+					// Enqueue the work item
+					_workItems.Enqueue(workItem);
+				}
+			}
+            return true;
+		}
+
+
+		/// <summary>
+		/// Waits for a work item or exits on timeout or cancel
+		/// </summary>
+		/// <param name="millisecondsTimeout">Timeout in milliseconds</param>
+		/// <param name="cancelEvent">Cancel wait handle</param>
+		/// <returns>Returns true if the resource was granted</returns>
+		public WorkItem DequeueWorkItem(
+			int millisecondsTimeout, 
+			WaitHandle cancelEvent)
+		{
+			// This method cause the caller to wait for a work item.
+			// If there is at least one waiting work item then the 
+			// method returns immidiately with it.
+			// 
+			// If there are no waiting work items then the caller 
+			// is queued between other waiters for a work item to arrive.
+			// 
+			// If a work item didn't come within millisecondsTimeout or 
+			// the user canceled the wait by signaling the cancelEvent 
+			// then the method returns null to indicate that the caller 
+			// didn't get a work item.
+
+			WaiterEntry waiterEntry;
+			WorkItem workItem = null;
+		    lock (this)
+		    {
+                ValidateNotDisposed();
+
+                // If there are waiting work items then take one and return.
+                if (_workItems.Count > 0)
+                {
+                    workItem = _workItems.Dequeue() as WorkItem;
+                    return workItem;
+                }
+
+                // No waiting work items ...
+
+                // Get the waiter entry for the waiters queue
+                waiterEntry = GetThreadWaiterEntry();
+
+                // Put the waiter with the other waiters
+                PushWaiter(waiterEntry);
+		    }
+
+		    // Prepare array of wait handle for the WaitHandle.WaitAny()
+            WaitHandle [] waitHandles = new WaitHandle[] { 
+																waiterEntry.WaitHandle, 
+																cancelEvent };
+
+			// Wait for an available resource, cancel event, or timeout.
+
+			// During the wait we are supposes to exit the synchronization 
+			// domain. (Placing true as the third argument of the WaitAny())
+			// It just doesn't work, I don't know why, so I have two lock(this) 
+			// statments instead of one.
+
+            int index = STPEventWaitHandle.WaitAny(
+				waitHandles,
+				millisecondsTimeout, 
+				true);
+
+			lock(this)
+			{
+				// success is true if it got a work item.
+				bool success = (0 == index);
+
+				// The timeout variable is used only for readability.
+				// (We treat cancel as timeout)
+				bool timeout = !success;
+
+				// On timeout update the waiterEntry that it is timed out
+				if (timeout)
+				{
+					// The Timeout() fails if the waiter has already been signaled
+					timeout = waiterEntry.Timeout();
+
+					// On timeout remove the waiter from the queue.
+					// Note that the complexity is O(1).
+					if(timeout)
+					{
+						RemoveWaiter(waiterEntry, false);
+					}
+
+					// Again readability
+					success = !timeout;
+				}
+
+				// On success return the work item
+				if (success)
+				{
+					workItem = waiterEntry.WorkItem;
+
+					if (null == workItem)
+					{
+						workItem = _workItems.Dequeue() as WorkItem;
+					}
+				}
+			}
+			// On failure return null.
+			return workItem;
+		}
+
+        /// <summary>
+        /// Cleanup the work items queue, hence no more work 
+        /// items are allowed to be queue
+        /// </summary>
+        private void Cleanup()
+        {
+            lock(this)
+            {
+                // Deactivate only once
+                if (!_isWorkItemsQueueActive)
+                {
+                    return;
+                }
+
+                // Don't queue more work items
+                _isWorkItemsQueueActive = false;
+
+                foreach(WorkItem workItem in _workItems)
+                {
+                    workItem.DisposeOfState();
+                }
+
+                // Clear the work items that are already queued
+                _workItems.Clear();
+
+                // Note: 
+                // I don't iterate over the queue and dispose of work items's states, 
+                // since if a work item has a state object that is still in use in the 
+                // application then I must not dispose it.
+
+                // Tell the waiters that they were timed out.
+                // It won't signal them to exit, but to ignore their
+                // next work item.
+				while(_waitersCount > 0)
+				{
+					WaiterEntry waiterEntry = PopWaiter();
+					waiterEntry.Timeout();
+				}
+            }
+        }
+
+        public object[] GetStates()
+        {
+            lock (this)
+            {
+                object[] states = new object[_workItems.Count];
+                int i = 0;
+                foreach (WorkItem workItem in _workItems)
+                {
+                    states[i] = workItem.GetWorkItemResult().State;
+                    ++i;
+                }
+                return states;
+            }
+        }
+
+		#endregion
+
+		#region Private methods
+
+		/// <summary>
+		/// Returns the WaiterEntry of the current thread
+		/// </summary>
+		/// <returns></returns>
+		/// In order to avoid creation and destuction of WaiterEntry
+		/// objects each thread has its own WaiterEntry object.
+		private static WaiterEntry GetThreadWaiterEntry()
+		{
+			if (null == CurrentWaiterEntry)
+			{
+				CurrentWaiterEntry = new WaiterEntry();
+			}
+			CurrentWaiterEntry.Reset();
+			return CurrentWaiterEntry;
+		}
+
+		#region Waiters stack methods
+
+		/// <summary>
+		/// Push a new waiter into the waiter's stack
+		/// </summary>
+		/// <param name="newWaiterEntry">A waiter to put in the stack</param>
+		public void PushWaiter(WaiterEntry newWaiterEntry)
+		{
+			// Remove the waiter if it is already in the stack and 
+			// update waiter's count as needed
+			RemoveWaiter(newWaiterEntry, false);
+
+			// If the stack is empty then newWaiterEntry is the new head of the stack 
+			if (null == _headWaiterEntry._nextWaiterEntry)
+			{
+				_headWaiterEntry._nextWaiterEntry = newWaiterEntry;
+				newWaiterEntry._prevWaiterEntry = _headWaiterEntry;
+
+			}
+			// If the stack is not empty then put newWaiterEntry as the new head 
+			// of the stack.
+			else
+			{
+				// Save the old first waiter entry
+				WaiterEntry oldFirstWaiterEntry = _headWaiterEntry._nextWaiterEntry;
+
+                // Update the links
+				_headWaiterEntry._nextWaiterEntry = newWaiterEntry;
+				newWaiterEntry._nextWaiterEntry = oldFirstWaiterEntry;
+				newWaiterEntry._prevWaiterEntry = _headWaiterEntry;
+				oldFirstWaiterEntry._prevWaiterEntry = newWaiterEntry;
+			}
+
+			// Increment the number of waiters
+			++_waitersCount;
+		}
+
+		/// <summary>
+		/// Pop a waiter from the waiter's stack
+		/// </summary>
+		/// <returns>Returns the first waiter in the stack</returns>
+		private WaiterEntry PopWaiter()
+		{
+			// Store the current stack head
+			WaiterEntry oldFirstWaiterEntry = _headWaiterEntry._nextWaiterEntry;
+
+			// Store the new stack head
+			WaiterEntry newHeadWaiterEntry = oldFirstWaiterEntry._nextWaiterEntry;
+
+			// Update the old stack head list links and decrement the number
+			// waiters.
+			RemoveWaiter(oldFirstWaiterEntry, true);
+
+			// Update the new stack head
+			_headWaiterEntry._nextWaiterEntry = newHeadWaiterEntry;
+			if (null != newHeadWaiterEntry)
+			{
+				newHeadWaiterEntry._prevWaiterEntry = _headWaiterEntry;
+			}
+
+			// Return the old stack head
+			return oldFirstWaiterEntry;
+		}
+
+		/// <summary>
+		/// Remove a waiter from the stack
+		/// </summary>
+		/// <param name="waiterEntry">A waiter entry to remove</param>
+		/// <param name="popDecrement">If true the waiter count is always decremented</param>
+		private void RemoveWaiter(WaiterEntry waiterEntry, bool popDecrement)
+		{
+			// Store the prev entry in the list
+			WaiterEntry prevWaiterEntry = waiterEntry._prevWaiterEntry;
+
+			// Store the next entry in the list
+			WaiterEntry nextWaiterEntry = waiterEntry._nextWaiterEntry;
+
+			// A flag to indicate if we need to decrement the waiters count.
+			// If we got here from PopWaiter then we must decrement.
+			// If we got here from PushWaiter then we decrement only if
+			// the waiter was already in the stack.
+			bool decrementCounter = popDecrement;
+
+			// Null the waiter's entry links
+			waiterEntry._prevWaiterEntry = null;
+			waiterEntry._nextWaiterEntry = null;
+
+			// If the waiter entry had a prev link then update it.
+			// It also means that the waiter is already in the list and we
+			// need to decrement the waiters count.
+			if (null != prevWaiterEntry)
+			{
+				prevWaiterEntry._nextWaiterEntry = nextWaiterEntry;
+				decrementCounter = true;
+			}
+
+			// If the waiter entry had a next link then update it.
+			// It also means that the waiter is already in the list and we
+			// need to decrement the waiters count.
+			if (null != nextWaiterEntry)
+			{
+				nextWaiterEntry._prevWaiterEntry = prevWaiterEntry;
+				decrementCounter = true;
+			}
+
+			// Decrement the waiters count if needed
+			if (decrementCounter)
+			{
+				--_waitersCount;
+			}
+		}
+
+		#endregion
+
+		#endregion
+
+		#region WaiterEntry class 
+
+		// A waiter entry in the _waiters queue.
+		public sealed class WaiterEntry : IDisposable
+		{
+			#region Member variables
+
+			/// <summary>
+			/// Event to signal the waiter that it got the work item.
+			/// </summary>
+			//private AutoResetEvent _waitHandle = new AutoResetEvent(false);
+            private AutoResetEvent _waitHandle = EventWaitHandleFactory.CreateAutoResetEvent();
+
+			/// <summary>
+			/// Flag to know if this waiter already quited from the queue 
+			/// because of a timeout.
+			/// </summary>
+			private bool _isTimedout = false;
+
+			/// <summary>
+			/// Flag to know if the waiter was signaled and got a work item. 
+			/// </summary>
+			private bool _isSignaled = false;
+
+            /// <summary>
+            /// A work item that passed directly to the waiter withou going 
+            /// through the queue
+            /// </summary>
+			private WorkItem _workItem = null;
+
+            private bool _isDisposed = false;
+
+			// Linked list members
+			internal WaiterEntry _nextWaiterEntry = null;
+			internal WaiterEntry _prevWaiterEntry = null;
+
+			#endregion
+
+			#region Construction
+
+			public WaiterEntry()
+			{
+				Reset();
+			}
+						
+			#endregion
+
+			#region Public methods
+
+			public WaitHandle WaitHandle
+			{
+				get { return _waitHandle; }
+			}
+
+			public WorkItem WorkItem
+			{
+				get
+				{
+					return _workItem;
+				}
+			}
+
+			/// <summary>
+			/// Signal the waiter that it got a work item.
+			/// </summary>
+			/// <returns>Return true on success</returns>
+			/// The method fails if Timeout() preceded its call
+			public bool Signal(WorkItem workItem)
+			{
+				lock(this)
+				{
+					if (!_isTimedout)
+					{
+						_workItem = workItem;
+						_isSignaled = true;
+						_waitHandle.Set();
+						return true;
+					}
+				}
+				return false;
+			}
+
+			/// <summary>
+			/// Mark the wait entry that it has been timed out
+			/// </summary>
+			/// <returns>Return true on success</returns>
+			/// The method fails if Signal() preceded its call
+			public bool Timeout()
+			{
+				lock(this)
+				{
+					// Time out can happen only if the waiter wasn't marked as
+					// signaled
+					if (!_isSignaled)
+					{
+						// We don't remove the waiter from the queue, the DequeueWorkItem 
+                        // method skips _waiters that were timed out.
+						_isTimedout = true;
+						return true;
+					}
+				}
+				return false;
+			}
+
+			/// <summary>
+			/// Reset the wait entry so it can be used again
+			/// </summary>
+			public void Reset()
+			{
+				_workItem = null;
+				_isTimedout = false;
+				_isSignaled = false;
+				_waitHandle.Reset();
+			}
+
+			/// <summary>
+			/// Free resources
+			/// </summary>
+			public void Close()
+			{
+				if (null != _waitHandle)
+				{
+					_waitHandle.Close();
+					_waitHandle = null;
+				}
+			}
+
+			#endregion
+
+			#region IDisposable Members
+
+			public void Dispose()
+			{
+                lock (this)
+                {
+                    if (!_isDisposed)
+                    {
+                        Close();
+                    }
+                    _isDisposed = true;
+                }
+            }
+
+			#endregion
+		}
+
+		#endregion
+
+        #region IDisposable Members
+
+        public void Dispose()
+        {
+            if (!_isDisposed)
+            {
+                Cleanup();
+            }
+            _isDisposed = true;
+        }
+
+        private void ValidateNotDisposed()
+        {
+            if(_isDisposed)
+            {
+                throw new ObjectDisposedException(GetType().ToString(), "The SmartThreadPool has been shutdown");
+            }
+        }
+
+        #endregion
+    }
+
+	#endregion
+}
+