Massive tab and trailing space cleanup
This commit is contained in:
178
ThirdParty/SmartThreadPool/CallerThreadContext.cs
vendored
178
ThirdParty/SmartThreadPool/CallerThreadContext.cs
vendored
@@ -13,125 +13,125 @@ 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
|
||||
{
|
||||
/// <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);
|
||||
// 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 readonly MethodInfo setLogicalCallContextMethodInfo =
|
||||
typeof(Thread).GetMethod("SetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
|
||||
private static string HttpContextSlotName = GetHttpContextSlotName();
|
||||
private static string HttpContextSlotName = GetHttpContextSlotName();
|
||||
|
||||
private static string GetHttpContextSlotName()
|
||||
{
|
||||
FieldInfo fi = typeof(HttpContext).GetField("CallContextSlotName", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
private static string GetHttpContextSlotName()
|
||||
{
|
||||
FieldInfo fi = typeof(HttpContext).GetField("CallContextSlotName", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
|
||||
if (fi != null)
|
||||
{
|
||||
return (string) fi.GetValue(null);
|
||||
}
|
||||
|
||||
return "HttpContext";
|
||||
}
|
||||
return "HttpContext";
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private fields
|
||||
|
||||
private HttpContext _httpContext;
|
||||
private LogicalCallContext _callContext;
|
||||
private HttpContext _httpContext;
|
||||
private LogicalCallContext _callContext;
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
private CallerThreadContext()
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
private CallerThreadContext()
|
||||
{
|
||||
}
|
||||
|
||||
public bool CapturedCallContext
|
||||
{
|
||||
get
|
||||
{
|
||||
return (null != _callContext);
|
||||
}
|
||||
}
|
||||
public bool CapturedCallContext
|
||||
{
|
||||
get
|
||||
{
|
||||
return (null != _callContext);
|
||||
}
|
||||
}
|
||||
|
||||
public bool CapturedHttpContext
|
||||
{
|
||||
get
|
||||
{
|
||||
return (null != _httpContext);
|
||||
}
|
||||
}
|
||||
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);
|
||||
/// <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();
|
||||
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();
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
// Capture httpContext
|
||||
if (captureHttpContext && (null != HttpContext.Current))
|
||||
{
|
||||
callerThreadContext._httpContext = HttpContext.Current;
|
||||
}
|
||||
|
||||
return callerThreadContext;
|
||||
}
|
||||
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");
|
||||
}
|
||||
/// <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 });
|
||||
}
|
||||
// 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)
|
||||
{
|
||||
// Restore HttpContext
|
||||
if (callerThreadContext._httpContext != null)
|
||||
{
|
||||
HttpContext.Current = callerThreadContext._httpContext;
|
||||
//CallContext.SetData(HttpContextSlotName, callerThreadContext._httpContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
//CallContext.SetData(HttpContextSlotName, callerThreadContext._httpContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
30
ThirdParty/SmartThreadPool/EventWaitHandle.cs
vendored
30
ThirdParty/SmartThreadPool/EventWaitHandle.cs
vendored
@@ -36,34 +36,34 @@ namespace Amib.Threading.Internal
|
||||
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++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
return nativeHandles;
|
||||
}
|
||||
|
||||
public static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
|
||||
{
|
||||
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);
|
||||
int result = WaitForMultipleObjects((uint)waitHandles.Length, nativeHandles, true, timeout);
|
||||
|
||||
if (result == WAIT_TIMEOUT || result == WAIT_FAILED)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
|
||||
public static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
|
||||
{
|
||||
uint timeout = millisecondsTimeout < 0 ? INFINITE : (uint)millisecondsTimeout;
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace Amib.Threading.Internal
|
||||
|
||||
return WaitAny(waitHandles, millisecondsTimeout, false);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region External methods
|
||||
|
||||
@@ -10,7 +10,7 @@ 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
|
||||
/// 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.
|
||||
@@ -57,7 +57,7 @@ namespace Amib.Threading.Internal
|
||||
/// <param name="initialState">The initial state of the event</param>
|
||||
private static void ReplaceEventHandle(WaitHandle waitHandle, bool manualReset, bool initialState)
|
||||
{
|
||||
// Store the old handle
|
||||
// Store the old handle
|
||||
IntPtr oldHandle = waitHandle.Handle;
|
||||
|
||||
// Create a new event
|
||||
@@ -67,7 +67,7 @@ namespace Amib.Threading.Internal
|
||||
waitHandle.Handle = newHandle;
|
||||
|
||||
// Close the old event
|
||||
CloseHandle (oldHandle);
|
||||
CloseHandle (oldHandle);
|
||||
}
|
||||
|
||||
[DllImport("coredll.dll", SetLastError = true)]
|
||||
|
||||
420
ThirdParty/SmartThreadPool/Interfaces.cs
vendored
420
ThirdParty/SmartThreadPool/Interfaces.cs
vendored
@@ -3,18 +3,18 @@ using System.Threading;
|
||||
|
||||
namespace Amib.Threading
|
||||
{
|
||||
#region Delegates
|
||||
#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 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>
|
||||
/// <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>
|
||||
@@ -23,56 +23,56 @@ namespace Amib.Threading
|
||||
/// <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 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
|
||||
/// 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
|
||||
/// 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
|
||||
#endregion
|
||||
|
||||
#region WorkItem Priority
|
||||
#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,
|
||||
}
|
||||
public enum WorkItemPriority
|
||||
{
|
||||
Lowest,
|
||||
BelowNormal,
|
||||
Normal,
|
||||
AboveNormal,
|
||||
Highest,
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region IWorkItemsGroup interface
|
||||
#region IWorkItemsGroup interface
|
||||
|
||||
/// <summary>
|
||||
/// 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>
|
||||
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
|
||||
@@ -115,14 +115,14 @@ namespace Amib.Threading
|
||||
/// <summary>
|
||||
/// Wait for all work item to complete.
|
||||
/// </summary>
|
||||
void WaitForIdle();
|
||||
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);
|
||||
bool WaitForIdle(TimeSpan timeout);
|
||||
|
||||
/// <summary>
|
||||
/// Wait for all work item to complete, until timeout expired
|
||||
@@ -150,7 +150,7 @@ namespace Amib.Threading
|
||||
/// Queue a work item
|
||||
/// </summary>
|
||||
/// <param name="callback">A callback to execute</param>
|
||||
/// <returns>Returns a work item result</returns>
|
||||
/// <returns>Returns a work item result</returns>
|
||||
IWorkItemResult QueueWorkItem(WorkItemCallback callback);
|
||||
|
||||
/// <summary>
|
||||
@@ -166,7 +166,7 @@ namespace Amib.Threading
|
||||
/// </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.
|
||||
/// 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);
|
||||
@@ -176,7 +176,7 @@ namespace Amib.Threading
|
||||
/// </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.
|
||||
/// 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>
|
||||
@@ -187,7 +187,7 @@ namespace Amib.Threading
|
||||
/// </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.
|
||||
/// 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
|
||||
@@ -200,7 +200,7 @@ namespace Amib.Threading
|
||||
/// </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.
|
||||
/// 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
|
||||
@@ -214,7 +214,7 @@ namespace Amib.Threading
|
||||
/// </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.
|
||||
/// 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
|
||||
@@ -228,7 +228,7 @@ namespace Amib.Threading
|
||||
/// </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.
|
||||
/// 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
|
||||
@@ -252,7 +252,7 @@ namespace Amib.Threading
|
||||
/// <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.
|
||||
/// 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);
|
||||
@@ -328,72 +328,72 @@ namespace Amib.Threading
|
||||
/// <summary>
|
||||
/// Queue a work item.
|
||||
/// </summary>
|
||||
/// <returns>Returns a IWorkItemResult<TResult> object.
|
||||
/// <returns>Returns a IWorkItemResult<TResult> 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<TResult> object.
|
||||
/// <returns>Returns a IWorkItemResult<TResult> 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<TResult> object.
|
||||
/// <returns>Returns a IWorkItemResult<TResult> 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<TResult> object.
|
||||
/// <returns>Returns a IWorkItemResult<TResult> 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<TResult> object.
|
||||
/// <returns>Returns a IWorkItemResult<TResult> 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
|
||||
#endregion
|
||||
|
||||
#region CallToPostExecute enumerator
|
||||
#region CallToPostExecute enumerator
|
||||
|
||||
[Flags]
|
||||
public enum CallToPostExecute
|
||||
{
|
||||
[Flags]
|
||||
public enum CallToPostExecute
|
||||
{
|
||||
/// <summary>
|
||||
/// Never call to the PostExecute call back
|
||||
/// </summary>
|
||||
Never = 0x00,
|
||||
Never = 0x00,
|
||||
|
||||
/// <summary>
|
||||
/// Call to the PostExecute only when the work item is cancelled
|
||||
/// </summary>
|
||||
WhenWorkItemCanceled = 0x01,
|
||||
WhenWorkItemCanceled = 0x01,
|
||||
|
||||
/// <summary>
|
||||
/// Call to the PostExecute only when the work item is not cancelled
|
||||
/// </summary>
|
||||
WhenWorkItemNotCanceled = 0x02,
|
||||
WhenWorkItemNotCanceled = 0x02,
|
||||
|
||||
/// <summary>
|
||||
/// Always call to the PostExecute
|
||||
/// </summary>
|
||||
Always = WhenWorkItemCanceled | WhenWorkItemNotCanceled,
|
||||
}
|
||||
Always = WhenWorkItemCanceled | WhenWorkItemNotCanceled,
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region IWorkItemResult interface
|
||||
#region IWorkItemResult interface
|
||||
|
||||
/// <summary>
|
||||
/// The common interface of IWorkItemResult and IWorkItemResult<T>
|
||||
@@ -421,159 +421,159 @@ namespace Amib.Threading
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// IWorkItemResult<TResult> interface.
|
||||
/// Created when a Func<TResult> work item is queued.
|
||||
/// </summary>
|
||||
/// </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>
|
||||
{
|
||||
/// <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
|
||||
/// <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);
|
||||
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.
|
||||
/// </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>
|
||||
/// <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 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>
|
||||
/// <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
|
||||
/// <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);
|
||||
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.
|
||||
/// </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>
|
||||
/// <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>
|
||||
/// 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 completed.
|
||||
/// </summary>
|
||||
bool IsCompleted { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets an indication whether the asynchronous operation has been canceled.
|
||||
/// </summary>
|
||||
bool IsCanceled { 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
|
||||
/// <summary>
|
||||
/// Gets the user-defined object that contains context data
|
||||
/// for the work item method.
|
||||
/// </summary>
|
||||
object State { get; }
|
||||
/// </summary>
|
||||
object State { get; }
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Same as Cancel(false).
|
||||
/// </summary>
|
||||
/// </summary>
|
||||
bool Cancel();
|
||||
|
||||
/// <summary>
|
||||
@@ -582,7 +582,7 @@ namespace Amib.Threading
|
||||
/// 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
|
||||
/// 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>
|
||||
@@ -590,23 +590,23 @@ namespace Amib.Threading
|
||||
/// <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>
|
||||
/// Get the work item's priority
|
||||
/// </summary>
|
||||
WorkItemPriority WorkItemPriority { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Return the result, same as GetResult()
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Return the result, same as GetResult()
|
||||
/// </summary>
|
||||
TResult Result { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the exception if occured otherwise returns null.
|
||||
/// </summary>
|
||||
object Exception { get; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns the exception if occured otherwise returns null.
|
||||
/// </summary>
|
||||
object Exception { get; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region .NET 3.5
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Amib.Threading.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// This method is intent for internal use.
|
||||
/// </summary>
|
||||
/// </summary>
|
||||
IWorkItemResult GetWorkItemResult();
|
||||
}
|
||||
|
||||
|
||||
386
ThirdParty/SmartThreadPool/PriorityQueue.cs
vendored
386
ThirdParty/SmartThreadPool/PriorityQueue.cs
vendored
@@ -5,235 +5,235 @@ using System.Diagnostics;
|
||||
|
||||
namespace Amib.Threading.Internal
|
||||
{
|
||||
#region PriorityQueue class
|
||||
#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>
|
||||
/// 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>
|
||||
/// 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>
|
||||
/// <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>
|
||||
/// The total number of work items within the queues
|
||||
/// </summary>
|
||||
private int _workItemsCount;
|
||||
|
||||
/// <summary>
|
||||
/// Use with IEnumerable interface
|
||||
/// </summary>
|
||||
private int _version;
|
||||
/// <summary>
|
||||
/// Use with IEnumerable interface
|
||||
/// </summary>
|
||||
private int _version;
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Contructor
|
||||
#region Contructor
|
||||
|
||||
public PriorityQueue()
|
||||
{
|
||||
for(int i = 0; i < _queues.Length; ++i)
|
||||
{
|
||||
public PriorityQueue()
|
||||
{
|
||||
for(int i = 0; i < _queues.Length; ++i)
|
||||
{
|
||||
_queues[i] = new LinkedList<IHasWorkItemPriority>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Enqueue a work item.
|
||||
/// </summary>
|
||||
/// <param name="workItem">A work item</param>
|
||||
public void Enqueue(IHasWorkItemPriority workItem)
|
||||
{
|
||||
Debug.Assert(null != workItem);
|
||||
/// <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);
|
||||
int queueIndex = _queuesCount-(int)workItem.WorkItemPriority-1;
|
||||
Debug.Assert(queueIndex >= 0);
|
||||
Debug.Assert(queueIndex < _queuesCount);
|
||||
|
||||
_queues[queueIndex].AddLast(workItem);
|
||||
++_workItemsCount;
|
||||
++_version;
|
||||
}
|
||||
_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;
|
||||
/// <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);
|
||||
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;
|
||||
}
|
||||
_queues[queueIndex].RemoveFirst();
|
||||
Debug.Assert(null != workItem);
|
||||
--_workItemsCount;
|
||||
++_version;
|
||||
}
|
||||
|
||||
return workItem;
|
||||
}
|
||||
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>
|
||||
/// 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>
|
||||
/// 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;
|
||||
}
|
||||
}
|
||||
/// <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
|
||||
#endregion
|
||||
|
||||
#region IEnumerable Members
|
||||
#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);
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns an enumerator to iterate over the work items
|
||||
/// </summary>
|
||||
/// <returns>Returns an enumerator</returns>
|
||||
public IEnumerator GetEnumerator()
|
||||
{
|
||||
return new PriorityQueueEnumerator(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region PriorityQueueEnumerator
|
||||
#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;
|
||||
/// <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;
|
||||
}
|
||||
}
|
||||
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
|
||||
#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 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 object Current
|
||||
{
|
||||
get
|
||||
{
|
||||
Debug.Assert(null != _enumerator);
|
||||
return _enumerator.Current;
|
||||
}
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (null == _enumerator)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (null == _enumerator)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(_version != _priorityQueue._version)
|
||||
{
|
||||
throw new InvalidOperationException("The collection has been modified");
|
||||
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;
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
|
||||
526
ThirdParty/SmartThreadPool/STPPerformanceCounter.cs
vendored
526
ThirdParty/SmartThreadPool/STPPerformanceCounter.cs
vendored
@@ -26,188 +26,188 @@ namespace Amib.Threading.Internal
|
||||
#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
|
||||
|
||||
internal enum STPPerformanceCounterType
|
||||
{
|
||||
// Fields
|
||||
ActiveThreads = 0,
|
||||
InUseThreads = 1,
|
||||
OverheadThreads = 2,
|
||||
OverheadThreadsPercent = 3,
|
||||
OverheadThreadsPercentBase = 4,
|
||||
{
|
||||
// Fields
|
||||
ActiveThreads = 0,
|
||||
InUseThreads = 1,
|
||||
OverheadThreads = 2,
|
||||
OverheadThreadsPercent = 3,
|
||||
OverheadThreadsPercentBase = 4,
|
||||
|
||||
WorkItems = 5,
|
||||
WorkItemsInQueue = 6,
|
||||
WorkItemsProcessed = 7,
|
||||
WorkItems = 5,
|
||||
WorkItemsInQueue = 6,
|
||||
WorkItemsProcessed = 7,
|
||||
|
||||
WorkItemsQueuedPerSecond = 8,
|
||||
WorkItemsProcessedPerSecond = 9,
|
||||
WorkItemsQueuedPerSecond = 8,
|
||||
WorkItemsProcessedPerSecond = 9,
|
||||
|
||||
AvgWorkItemWaitTime = 10,
|
||||
AvgWorkItemWaitTimeBase = 11,
|
||||
AvgWorkItemWaitTime = 10,
|
||||
AvgWorkItemWaitTimeBase = 11,
|
||||
|
||||
AvgWorkItemProcessTime = 12,
|
||||
AvgWorkItemProcessTimeBase = 13,
|
||||
AvgWorkItemProcessTime = 12,
|
||||
AvgWorkItemProcessTimeBase = 13,
|
||||
|
||||
WorkItemsGroups = 14,
|
||||
WorkItemsGroups = 14,
|
||||
|
||||
LastCounter = 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;
|
||||
}
|
||||
/// <summary>
|
||||
/// Summary description for STPPerformanceCounter.
|
||||
/// </summary>
|
||||
internal class STPPerformanceCounter
|
||||
{
|
||||
// Fields
|
||||
private readonly PerformanceCounterType _pcType;
|
||||
protected string _counterHelp;
|
||||
protected string _counterName;
|
||||
|
||||
public void AddCounterToCollection(CounterCreationDataCollection counterData)
|
||||
{
|
||||
CounterCreationData counterCreationData = new CounterCreationData(
|
||||
_counterName,
|
||||
_counterHelp,
|
||||
_pcType);
|
||||
// Methods
|
||||
public STPPerformanceCounter(
|
||||
string counterName,
|
||||
string counterHelp,
|
||||
PerformanceCounterType pcType)
|
||||
{
|
||||
_counterName = counterName;
|
||||
_counterHelp = counterHelp;
|
||||
_pcType = pcType;
|
||||
}
|
||||
|
||||
counterData.Add(counterCreationData);
|
||||
}
|
||||
|
||||
// Properties
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _counterName;
|
||||
}
|
||||
}
|
||||
}
|
||||
public void AddCounterToCollection(CounterCreationDataCollection counterData)
|
||||
{
|
||||
CounterCreationData counterCreationData = new CounterCreationData(
|
||||
_counterName,
|
||||
_counterHelp,
|
||||
_pcType);
|
||||
|
||||
internal class STPPerformanceCounters
|
||||
{
|
||||
// Fields
|
||||
internal STPPerformanceCounter[] _stpPerformanceCounters;
|
||||
private static readonly STPPerformanceCounters _instance;
|
||||
internal const string _stpCategoryHelp = "SmartThreadPool performance counters";
|
||||
internal const string _stpCategoryName = "SmartThreadPool";
|
||||
counterData.Add(counterCreationData);
|
||||
}
|
||||
|
||||
// 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),
|
||||
// Properties
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _counterName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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),
|
||||
internal class STPPerformanceCounters
|
||||
{
|
||||
// Fields
|
||||
internal STPPerformanceCounter[] _stpPerformanceCounters;
|
||||
private static readonly STPPerformanceCounters _instance;
|
||||
internal const string _stpCategoryHelp = "SmartThreadPool performance counters";
|
||||
internal const string _stpCategoryName = "SmartThreadPool";
|
||||
|
||||
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),
|
||||
// Methods
|
||||
static STPPerformanceCounters()
|
||||
{
|
||||
_instance = new STPPerformanceCounters();
|
||||
}
|
||||
|
||||
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),
|
||||
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("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", "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 Groups", "The current number of work item groups associated with the Smart Thread Pool.", 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),
|
||||
|
||||
_stpPerformanceCounters = stpPerformanceCounters;
|
||||
SetupCategory();
|
||||
}
|
||||
|
||||
private void SetupCategory()
|
||||
{
|
||||
if (!PerformanceCounterCategory.Exists(_stpCategoryName))
|
||||
{
|
||||
CounterCreationDataCollection counters = new CounterCreationDataCollection();
|
||||
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),
|
||||
|
||||
for (int i = 0; i < _stpPerformanceCounters.Length; i++)
|
||||
{
|
||||
_stpPerformanceCounters[i].AddCounterToCollection(counters);
|
||||
}
|
||||
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),
|
||||
|
||||
PerformanceCounterCategory.Create(
|
||||
_stpCategoryName,
|
||||
_stpCategoryHelp,
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
counters);
|
||||
|
||||
internal class STPInstancePerformanceCounter : IDisposable
|
||||
{
|
||||
// Fields
|
||||
}
|
||||
}
|
||||
|
||||
// Properties
|
||||
public static STPPerformanceCounters Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class STPInstancePerformanceCounter : IDisposable
|
||||
{
|
||||
// Fields
|
||||
private bool _isDisposed;
|
||||
private PerformanceCounter _pcs;
|
||||
private PerformanceCounter _pcs;
|
||||
|
||||
// Methods
|
||||
protected STPInstancePerformanceCounter()
|
||||
{
|
||||
// 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 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()
|
||||
{
|
||||
public void Close()
|
||||
{
|
||||
if (_pcs != null)
|
||||
{
|
||||
_pcs.RemoveInstance();
|
||||
_pcs.Close();
|
||||
_pcs = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Dispose(bool disposing)
|
||||
{
|
||||
@@ -220,90 +220,90 @@ namespace Amib.Threading.Internal
|
||||
}
|
||||
_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;
|
||||
}
|
||||
}
|
||||
public virtual void Increment()
|
||||
{
|
||||
_pcs.Increment();
|
||||
}
|
||||
|
||||
internal class STPInstanceNullPerformanceCounter : STPInstancePerformanceCounter
|
||||
{
|
||||
// Methods
|
||||
public override void Increment() {}
|
||||
public override void IncrementBy(long value) {}
|
||||
public override void Set(long val) {}
|
||||
}
|
||||
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
|
||||
{
|
||||
internal class STPInstancePerformanceCounters : ISTPInstancePerformanceCounters
|
||||
{
|
||||
private bool _isDisposed;
|
||||
// Fields
|
||||
private STPInstancePerformanceCounter[] _pcs;
|
||||
private static readonly STPInstancePerformanceCounter _stpInstanceNullPerformanceCounter;
|
||||
// Fields
|
||||
private STPInstancePerformanceCounter[] _pcs;
|
||||
private static readonly STPInstancePerformanceCounter _stpInstanceNullPerformanceCounter;
|
||||
|
||||
// Methods
|
||||
static STPInstancePerformanceCounters()
|
||||
{
|
||||
_stpInstanceNullPerformanceCounter = new STPInstanceNullPerformanceCounter();
|
||||
}
|
||||
|
||||
public STPInstancePerformanceCounters(string instance)
|
||||
{
|
||||
// Methods
|
||||
static STPInstancePerformanceCounters()
|
||||
{
|
||||
_stpInstanceNullPerformanceCounter = new STPInstanceNullPerformanceCounter();
|
||||
}
|
||||
|
||||
public STPInstancePerformanceCounters(string instance)
|
||||
{
|
||||
_isDisposed = false;
|
||||
_pcs = new STPInstancePerformanceCounter[(int)STPPerformanceCounterType.LastCounter];
|
||||
_pcs = new STPInstancePerformanceCounter[(int)STPPerformanceCounterType.LastCounter];
|
||||
|
||||
// Call the STPPerformanceCounters.Instance so the static constructor will
|
||||
// intialize the STPPerformanceCounters singleton.
|
||||
STPPerformanceCounters.Instance.GetHashCode();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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++)
|
||||
{
|
||||
|
||||
public void Close()
|
||||
{
|
||||
if (null != _pcs)
|
||||
{
|
||||
for (int i = 0; i < _pcs.Length; i++)
|
||||
{
|
||||
if (null != _pcs[i])
|
||||
{
|
||||
_pcs[i].Dispose();
|
||||
}
|
||||
}
|
||||
_pcs = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
_pcs = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Dispose(bool disposing)
|
||||
{
|
||||
@@ -316,62 +316,62 @@ namespace Amib.Threading.Internal
|
||||
}
|
||||
_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);
|
||||
private STPInstancePerformanceCounter GetCounter(STPPerformanceCounterType spcType)
|
||||
{
|
||||
return _pcs[(int) spcType];
|
||||
}
|
||||
|
||||
GetCounter(STPPerformanceCounterType.OverheadThreadsPercentBase).Set(activeThreads-inUseThreads);
|
||||
GetCounter(STPPerformanceCounterType.OverheadThreadsPercent).Set(inUseThreads);
|
||||
}
|
||||
public void SampleThreads(long activeThreads, long inUseThreads)
|
||||
{
|
||||
GetCounter(STPPerformanceCounterType.ActiveThreads).Set(activeThreads);
|
||||
GetCounter(STPPerformanceCounterType.InUseThreads).Set(inUseThreads);
|
||||
GetCounter(STPPerformanceCounterType.OverheadThreads).Set(activeThreads-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.OverheadThreadsPercentBase).Set(activeThreads-inUseThreads);
|
||||
GetCounter(STPPerformanceCounterType.OverheadThreadsPercent).Set(inUseThreads);
|
||||
}
|
||||
|
||||
GetCounter(STPPerformanceCounterType.WorkItemsQueuedPerSecond).Set(workItemsQueued);
|
||||
GetCounter(STPPerformanceCounterType.WorkItemsProcessedPerSecond).Set(workItemsProcessed);
|
||||
}
|
||||
public void SampleWorkItems(long workItemsQueued, long workItemsProcessed)
|
||||
{
|
||||
GetCounter(STPPerformanceCounterType.WorkItems).Set(workItemsQueued+workItemsProcessed);
|
||||
GetCounter(STPPerformanceCounterType.WorkItemsInQueue).Set(workItemsQueued);
|
||||
GetCounter(STPPerformanceCounterType.WorkItemsProcessed).Set(workItemsProcessed);
|
||||
|
||||
public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime)
|
||||
{
|
||||
GetCounter(STPPerformanceCounterType.AvgWorkItemWaitTime).IncrementBy((long)workItemWaitTime.TotalMilliseconds);
|
||||
GetCounter(STPPerformanceCounterType.AvgWorkItemWaitTimeBase).Increment();
|
||||
}
|
||||
GetCounter(STPPerformanceCounterType.WorkItemsQueuedPerSecond).Set(workItemsQueued);
|
||||
GetCounter(STPPerformanceCounterType.WorkItemsProcessedPerSecond).Set(workItemsProcessed);
|
||||
}
|
||||
|
||||
public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime)
|
||||
{
|
||||
GetCounter(STPPerformanceCounterType.AvgWorkItemProcessTime).IncrementBy((long)workItemProcessTime.TotalMilliseconds);
|
||||
GetCounter(STPPerformanceCounterType.AvgWorkItemProcessTimeBase).Increment();
|
||||
}
|
||||
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();
|
||||
{
|
||||
private static readonly NullSTPInstancePerformanceCounters _instance = new NullSTPInstancePerformanceCounters();
|
||||
|
||||
public static NullSTPInstancePerformanceCounters Instance
|
||||
{
|
||||
get { return _instance; }
|
||||
}
|
||||
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 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; }
|
||||
@@ -391,7 +391,7 @@ namespace Amib.Threading.Internal
|
||||
{
|
||||
get { return 0; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class LocalSTPInstancePerformanceCounters : ISTPInstancePerformanceCounters, ISTPPerformanceCountersReader
|
||||
{
|
||||
|
||||
148
ThirdParty/SmartThreadPool/STPStartInfo.cs
vendored
148
ThirdParty/SmartThreadPool/STPStartInfo.cs
vendored
@@ -3,9 +3,9 @@ using System.Threading;
|
||||
|
||||
namespace Amib.Threading
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for STPStartInfo.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Summary description for STPStartInfo.
|
||||
/// </summary>
|
||||
public class STPStartInfo : WIGStartInfo
|
||||
{
|
||||
private int _idleTimeout = SmartThreadPool.DefaultIdleTimeout;
|
||||
@@ -31,7 +31,7 @@ namespace Amib.Threading
|
||||
_minWorkerThreads = SmartThreadPool.DefaultMinWorkerThreads;
|
||||
}
|
||||
|
||||
public STPStartInfo(STPStartInfo stpStartInfo)
|
||||
public STPStartInfo(STPStartInfo stpStartInfo)
|
||||
: base(stpStartInfo)
|
||||
{
|
||||
_idleTimeout = stpStartInfo.IdleTimeout;
|
||||
@@ -48,63 +48,63 @@ namespace Amib.Threading
|
||||
_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
|
||||
|
||||
/// <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;
|
||||
_idleTimeout = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get/Set the lower limit of threads in the pool.
|
||||
/// </summary>
|
||||
public virtual int MinWorkerThreads
|
||||
{
|
||||
get { return _minWorkerThreads; }
|
||||
set
|
||||
/// <summary>
|
||||
/// Get/Set the lower limit of threads in the pool.
|
||||
/// </summary>
|
||||
public virtual int MinWorkerThreads
|
||||
{
|
||||
get { return _minWorkerThreads; }
|
||||
set
|
||||
{
|
||||
ThrowIfReadOnly();
|
||||
_minWorkerThreads = value;
|
||||
_minWorkerThreads = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get/Set the upper limit of threads in the pool.
|
||||
/// </summary>
|
||||
public virtual int MaxWorkerThreads
|
||||
{
|
||||
get { return _maxWorkerThreads; }
|
||||
set
|
||||
/// <summary>
|
||||
/// Get/Set the upper limit of threads in the pool.
|
||||
/// </summary>
|
||||
public virtual int MaxWorkerThreads
|
||||
{
|
||||
get { return _maxWorkerThreads; }
|
||||
set
|
||||
{
|
||||
ThrowIfReadOnly();
|
||||
_maxWorkerThreads = value;
|
||||
_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
|
||||
/// <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;
|
||||
_threadPriority = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Get/Set the thread pool name. Threads will get names depending on this.
|
||||
@@ -118,50 +118,50 @@ namespace Amib.Threading
|
||||
}
|
||||
}
|
||||
|
||||
/// <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
|
||||
/// <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;
|
||||
_performanceCounterInstanceName = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enable/Disable the local performance counter.
|
||||
/// This enables the user to get some performance information about the SmartThreadPool
|
||||
/// 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;
|
||||
}
|
||||
}
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
public virtual bool AreThreadsBackground
|
||||
{
|
||||
get { return _areThreadsBackground; }
|
||||
set
|
||||
{
|
||||
ThrowIfReadOnly ();
|
||||
_areThreadsBackground = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Get a readonly version of this STPStartInfo.
|
||||
/// </summary>
|
||||
/// <returns>Returns a readonly reference to this STPStartInfo</returns>
|
||||
@@ -185,10 +185,10 @@ namespace Amib.Threading
|
||||
ThrowIfReadOnly();
|
||||
_apartmentState = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get/Set the max stack size of threads in the thread pool
|
||||
/// </summary>
|
||||
|
||||
@@ -26,15 +26,15 @@ namespace Amib.Threading
|
||||
/// <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
|
||||
/// 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
|
||||
/// A reference to the current work item a thread from the thread pool
|
||||
/// is executing.
|
||||
/// </summary>
|
||||
/// </summary>
|
||||
public WorkItem CurrentWorkItem { get; set; }
|
||||
|
||||
public ThreadEntry(SmartThreadPool stp)
|
||||
|
||||
1570
ThirdParty/SmartThreadPool/SmartThreadPool.cs
vendored
1570
ThirdParty/SmartThreadPool/SmartThreadPool.cs
vendored
File diff suppressed because it is too large
Load Diff
198
ThirdParty/SmartThreadPool/WIGStartInfo.cs
vendored
198
ThirdParty/SmartThreadPool/WIGStartInfo.cs
vendored
@@ -2,11 +2,11 @@ using System;
|
||||
|
||||
namespace Amib.Threading
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for WIGStartInfo.
|
||||
/// </summary>
|
||||
public class WIGStartInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for WIGStartInfo.
|
||||
/// </summary>
|
||||
public class WIGStartInfo
|
||||
{
|
||||
private bool _useCallerCallContext;
|
||||
private bool _useCallerHttpContext;
|
||||
private bool _disposeOfStateObjects;
|
||||
@@ -18,10 +18,10 @@ namespace Amib.Threading
|
||||
|
||||
protected bool _readOnly;
|
||||
|
||||
public WIGStartInfo()
|
||||
public WIGStartInfo()
|
||||
{
|
||||
_fillStateWithArgs = SmartThreadPool.DefaultFillStateWithArgs;
|
||||
_workItemPriority = SmartThreadPool.DefaultWorkItemPriority;
|
||||
_fillStateWithArgs = SmartThreadPool.DefaultFillStateWithArgs;
|
||||
_workItemPriority = SmartThreadPool.DefaultWorkItemPriority;
|
||||
_startSuspended = SmartThreadPool.DefaultStartSuspended;
|
||||
_postExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback;
|
||||
_callToPostExecute = SmartThreadPool.DefaultCallToPostExecute;
|
||||
@@ -30,7 +30,7 @@ namespace Amib.Threading
|
||||
_useCallerCallContext = SmartThreadPool.DefaultUseCallerCallContext;
|
||||
}
|
||||
|
||||
public WIGStartInfo(WIGStartInfo wigStartInfo)
|
||||
public WIGStartInfo(WIGStartInfo wigStartInfo)
|
||||
{
|
||||
_useCallerCallContext = wigStartInfo.UseCallerCallContext;
|
||||
_useCallerHttpContext = wigStartInfo.UseCallerHttpContext;
|
||||
@@ -50,122 +50,122 @@ namespace Amib.Threading
|
||||
}
|
||||
}
|
||||
|
||||
/// <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 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 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 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 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 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 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 default priority that a work item gets when it is enqueued
|
||||
/// </summary>
|
||||
public virtual WorkItemPriority WorkItemPriority
|
||||
{
|
||||
get { return _workItemPriority; }
|
||||
set { _workItemPriority = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Get/Set the if QueueWorkItem of Action<...>/Func<...> fill the
|
||||
/// arguments as an object array into the state of the work item.
|
||||
/// The arguments can be access later by IWorkItemResult.State.
|
||||
/// </summary>
|
||||
public virtual bool FillStateWithArgs
|
||||
{
|
||||
get { return _fillStateWithArgs; }
|
||||
set
|
||||
{
|
||||
ThrowIfReadOnly();
|
||||
_fillStateWithArgs = value;
|
||||
/// 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>
|
||||
/// <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 };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
20
ThirdParty/SmartThreadPool/WorkItem.cs
vendored
20
ThirdParty/SmartThreadPool/WorkItem.cs
vendored
@@ -88,7 +88,7 @@ namespace Amib.Threading.Internal
|
||||
private ManualResetEvent _workItemCompleted;
|
||||
|
||||
/// <summary>
|
||||
/// A reference count to the _workItemCompleted.
|
||||
/// A reference count to the _workItemCompleted.
|
||||
/// When it reaches to zero _workItemCompleted is Closed
|
||||
/// </summary>
|
||||
private int _workItemCompletedRefCount;
|
||||
@@ -114,13 +114,13 @@ namespace Amib.Threading.Internal
|
||||
private event WorkItemStateCallback _workItemCompletedEvent;
|
||||
|
||||
/// <summary>
|
||||
/// A reference to an object that indicates whatever the
|
||||
/// A reference to an object that indicates whatever the
|
||||
/// WorkItemsGroup has been canceled
|
||||
/// </summary>
|
||||
private CanceledWorkItemsGroup _canceledWorkItemsGroup = CanceledWorkItemsGroup.NotCanceledWorkItemsGroup;
|
||||
|
||||
/// <summary>
|
||||
/// A reference to an object that indicates whatever the
|
||||
/// A reference to an object that indicates whatever the
|
||||
/// SmartThreadPool has been canceled
|
||||
/// </summary>
|
||||
private CanceledWorkItemsGroup _canceledSmartThreadPool = CanceledWorkItemsGroup.NotCanceledWorkItemsGroup;
|
||||
@@ -197,7 +197,7 @@ namespace Amib.Threading.Internal
|
||||
/// <param name="workItemInfo">The WorkItemInfo of te workitem</param>
|
||||
/// <param name="callback">Callback delegate for the callback.</param>
|
||||
/// <param name="state">State with which to call the callback delegate.</param>
|
||||
///
|
||||
///
|
||||
/// We assume that the WorkItem object is created within the thread
|
||||
/// that meant to run the callback
|
||||
public WorkItem(
|
||||
@@ -402,7 +402,7 @@ namespace Amib.Threading.Internal
|
||||
{
|
||||
tae.GetHashCode();
|
||||
// Check if the work item was cancelled
|
||||
// If we got a ThreadAbortException and the STP is not shutting down, it means the
|
||||
// If we got a ThreadAbortException and the STP is not shutting down, it means the
|
||||
// work items was cancelled.
|
||||
if (!SmartThreadPool.CurrentThreadEntry.AssociatedSmartThreadPool.IsShuttingdown)
|
||||
{
|
||||
@@ -471,7 +471,7 @@ namespace Amib.Threading.Internal
|
||||
/// <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.
|
||||
/// 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>
|
||||
@@ -553,7 +553,7 @@ namespace Amib.Threading.Internal
|
||||
/// <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.
|
||||
/// 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>
|
||||
@@ -734,7 +734,7 @@ namespace Amib.Threading.Internal
|
||||
// so it already signaled its completion.
|
||||
//signalComplete = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
success = true;
|
||||
break;
|
||||
case WorkItemState.Completed:
|
||||
@@ -856,7 +856,7 @@ namespace Amib.Threading.Internal
|
||||
{
|
||||
case 0:
|
||||
// The work item signaled
|
||||
// Note that the signal could be also as a result of canceling the
|
||||
// Note that the signal could be also as a result of canceling the
|
||||
// work item (not the get result)
|
||||
break;
|
||||
case 1:
|
||||
@@ -884,7 +884,7 @@ namespace Amib.Threading.Internal
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A wait handle to wait for completion, cancel, or timeout
|
||||
/// A wait handle to wait for completion, cancel, or timeout
|
||||
/// </summary>
|
||||
private WaitHandle GetWaitHandle()
|
||||
{
|
||||
|
||||
564
ThirdParty/SmartThreadPool/WorkItemFactory.cs
vendored
564
ThirdParty/SmartThreadPool/WorkItemFactory.cs
vendored
@@ -2,146 +2,146 @@ using System;
|
||||
|
||||
namespace Amib.Threading.Internal
|
||||
{
|
||||
#region WorkItemFactory class
|
||||
#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>
|
||||
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>
|
||||
/// <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);
|
||||
}
|
||||
/// <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>
|
||||
/// <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);
|
||||
}
|
||||
/// <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>
|
||||
/// <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;
|
||||
/// <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;
|
||||
}
|
||||
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>
|
||||
/// <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>
|
||||
/// <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,
|
||||
@@ -161,183 +161,183 @@ namespace Amib.Threading.Internal
|
||||
return workItem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new work item
|
||||
/// </summary>
|
||||
/// <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);
|
||||
/// <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 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);
|
||||
WorkItem workItem = new WorkItem(
|
||||
workItemsGroup,
|
||||
workItemInfo,
|
||||
callback,
|
||||
state);
|
||||
|
||||
return workItem;
|
||||
}
|
||||
return workItem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new work item
|
||||
/// </summary>
|
||||
/// <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);
|
||||
/// <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;
|
||||
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);
|
||||
WorkItem workItem = new WorkItem(
|
||||
workItemsGroup,
|
||||
workItemInfo,
|
||||
callback,
|
||||
state);
|
||||
|
||||
return workItem;
|
||||
}
|
||||
return workItem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new work item
|
||||
/// </summary>
|
||||
/// <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);
|
||||
/// <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 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);
|
||||
WorkItem workItem = new WorkItem(
|
||||
workItemsGroup,
|
||||
workItemInfo,
|
||||
callback,
|
||||
state);
|
||||
|
||||
return workItem;
|
||||
}
|
||||
return workItem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new work item
|
||||
/// </summary>
|
||||
/// <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)
|
||||
{
|
||||
/// <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);
|
||||
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;
|
||||
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;
|
||||
}
|
||||
WorkItem workItem = new WorkItem(
|
||||
workItemsGroup,
|
||||
workItemInfo,
|
||||
callback,
|
||||
state);
|
||||
|
||||
private static void ValidateCallback(Delegate callback)
|
||||
{
|
||||
return workItem;
|
||||
}
|
||||
|
||||
private static void ValidateCallback(Delegate callback)
|
||||
{
|
||||
if (callback != null && callback.GetInvocationList().Length > 1)
|
||||
{
|
||||
throw new NotSupportedException("SmartThreadPool doesn't support delegates chains");
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
throw new NotSupportedException("SmartThreadPool doesn't support delegates chains");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
|
||||
104
ThirdParty/SmartThreadPool/WorkItemInfo.cs
vendored
104
ThirdParty/SmartThreadPool/WorkItemInfo.cs
vendored
@@ -1,69 +1,69 @@
|
||||
namespace Amib.Threading
|
||||
{
|
||||
#region WorkItemInfo class
|
||||
#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;
|
||||
}
|
||||
/// <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;
|
||||
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 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 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 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>
|
||||
/// <summary>
|
||||
/// Get/Set the run the post execute options
|
||||
/// </summary>
|
||||
public CallToPostExecute CallToPostExecute { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Get/Set the post execute callback
|
||||
/// </summary>
|
||||
/// <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 priority
|
||||
/// </summary>
|
||||
public WorkItemPriority WorkItemPriority { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Get/Set the work item's timout in milliseconds.
|
||||
/// <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; }
|
||||
}
|
||||
/// </summary>
|
||||
public long Timeout { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
|
||||
414
ThirdParty/SmartThreadPool/WorkItemsGroup.cs
vendored
414
ThirdParty/SmartThreadPool/WorkItemsGroup.cs
vendored
@@ -6,107 +6,107 @@ using System.Diagnostics;
|
||||
namespace Amib.Threading.Internal
|
||||
{
|
||||
|
||||
#region WorkItemsGroup class
|
||||
#region WorkItemsGroup class
|
||||
|
||||
/// <summary>
|
||||
/// Summary description for WorkItemsGroup.
|
||||
/// </summary>
|
||||
public class WorkItemsGroup : WorkItemsGroupBase
|
||||
{
|
||||
#region Private members
|
||||
/// <summary>
|
||||
/// Summary description for WorkItemsGroup.
|
||||
/// </summary>
|
||||
public class WorkItemsGroup : WorkItemsGroupBase
|
||||
{
|
||||
#region Private members
|
||||
|
||||
private readonly object _lock = new object();
|
||||
private readonly object _lock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// A reference to the SmartThreadPool instance that created this
|
||||
/// WorkItemsGroup.
|
||||
/// </summary>
|
||||
private readonly SmartThreadPool _stp;
|
||||
/// <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>
|
||||
/// 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>
|
||||
/// 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>
|
||||
/// 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 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>
|
||||
/// 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>
|
||||
/// WorkItemsGroup start information
|
||||
/// </summary>
|
||||
private readonly WIGStartInfo _workItemsGroupStartInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Signaled when all of the WorkItemsGroup's work item completed.
|
||||
/// </summary>
|
||||
/// <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();
|
||||
/// <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
|
||||
#endregion
|
||||
|
||||
#region Construction
|
||||
#region Construction
|
||||
|
||||
public WorkItemsGroup(
|
||||
SmartThreadPool stp,
|
||||
int concurrency,
|
||||
WIGStartInfo wigStartInfo)
|
||||
{
|
||||
if (concurrency <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(
|
||||
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";
|
||||
}
|
||||
_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;
|
||||
// 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
|
||||
#endregion
|
||||
|
||||
#region WorkItemsGroupBase Overrides
|
||||
|
||||
@@ -146,7 +146,7 @@ namespace Amib.Threading.Internal
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// WorkItemsGroup start information
|
||||
/// </summary>
|
||||
public override WIGStartInfo WIGStartInfo
|
||||
@@ -154,38 +154,38 @@ namespace Amib.Threading.Internal
|
||||
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));
|
||||
}
|
||||
/// <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;
|
||||
|
||||
public override void Cancel(bool abortExecution)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_canceledWorkItemsGroup.IsCanceled = true;
|
||||
_workItemsQueue.Clear();
|
||||
_workItemsInStpQueue = 0;
|
||||
_canceledWorkItemsGroup = new CanceledWorkItemsGroup();
|
||||
}
|
||||
EnqueueToSTPNextNWorkItem(Math.Min(_workItemsQueue.Count, _concurrency));
|
||||
}
|
||||
|
||||
if (abortExecution)
|
||||
{
|
||||
_stp.CancelAbortWorkItemsGroup(this);
|
||||
}
|
||||
}
|
||||
public override void Cancel(bool abortExecution)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_canceledWorkItemsGroup.IsCanceled = true;
|
||||
_workItemsQueue.Clear();
|
||||
_workItemsInStpQueue = 0;
|
||||
_canceledWorkItemsGroup = new CanceledWorkItemsGroup();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
if (abortExecution)
|
||||
{
|
||||
_stp.CancelAbortWorkItemsGroup(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wait for the thread pool to be idle
|
||||
/// </summary>
|
||||
public override bool WaitForIdle(int millisecondsTimeout)
|
||||
@@ -194,34 +194,34 @@ namespace Amib.Threading.Internal
|
||||
return STPEventWaitHandle.WaitOne(_isIdleWaitHandle, millisecondsTimeout, false);
|
||||
}
|
||||
|
||||
public override event WorkItemsGroupIdleHandler OnIdle
|
||||
{
|
||||
add { _onIdle += value; }
|
||||
remove { _onIdle -= value; }
|
||||
}
|
||||
public override event WorkItemsGroupIdleHandler OnIdle
|
||||
{
|
||||
add { _onIdle += value; }
|
||||
remove { _onIdle -= value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
#region Private methods
|
||||
|
||||
private void RegisterToWorkItemCompletion(IWorkItemResult wir)
|
||||
{
|
||||
IInternalWorkItemResult iwir = (IInternalWorkItemResult)wir;
|
||||
iwir.OnWorkItemStarted += OnWorkItemStartedCallback;
|
||||
iwir.OnWorkItemCompleted += OnWorkItemCompletedCallback;
|
||||
}
|
||||
private void RegisterToWorkItemCompletion(IWorkItemResult wir)
|
||||
{
|
||||
IInternalWorkItemResult iwir = (IInternalWorkItemResult)wir;
|
||||
iwir.OnWorkItemStarted += OnWorkItemStartedCallback;
|
||||
iwir.OnWorkItemCompleted += OnWorkItemCompletedCallback;
|
||||
}
|
||||
|
||||
public void OnSTPIsStarting()
|
||||
{
|
||||
public void OnSTPIsStarting()
|
||||
{
|
||||
if (_isSuspended)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EnqueueToSTPNextNWorkItem(_concurrency);
|
||||
}
|
||||
|
||||
public void EnqueueToSTPNextNWorkItem(int count)
|
||||
EnqueueToSTPNextNWorkItem(_concurrency);
|
||||
}
|
||||
|
||||
public void EnqueueToSTPNextNWorkItem(int count)
|
||||
{
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
@@ -229,115 +229,115 @@ namespace Amib.Threading.Internal
|
||||
}
|
||||
}
|
||||
|
||||
private object FireOnIdle(object state)
|
||||
{
|
||||
FireOnIdleImpl(_onIdle);
|
||||
return null;
|
||||
}
|
||||
private object FireOnIdle(object state)
|
||||
{
|
||||
FireOnIdleImpl(_onIdle);
|
||||
return null;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private void FireOnIdleImpl(WorkItemsGroupIdleHandler onIdle)
|
||||
{
|
||||
if(null == onIdle)
|
||||
{
|
||||
return;
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private void FireOnIdleImpl(WorkItemsGroupIdleHandler onIdle)
|
||||
{
|
||||
if(null == onIdle)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Delegate[] delegates = onIdle.GetInvocationList();
|
||||
foreach(WorkItemsGroupIdleHandler eh in delegates)
|
||||
{
|
||||
try
|
||||
{
|
||||
eh(this);
|
||||
}
|
||||
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 OnWorkItemStartedCallback(WorkItem workItem)
|
||||
{
|
||||
lock(_lock)
|
||||
{
|
||||
++_workItemsExecutingInStp;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnWorkItemCompletedCallback(WorkItem workItem)
|
||||
{
|
||||
EnqueueToSTPNextWorkItem(null, true);
|
||||
}
|
||||
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)
|
||||
{
|
||||
EnqueueToSTPNextWorkItem(workItem, false);
|
||||
}
|
||||
|
||||
private void EnqueueToSTPNextWorkItem(WorkItem workItem, bool decrementWorkItemsInStpQueue)
|
||||
{
|
||||
lock(_lock)
|
||||
{
|
||||
// Got here from OnWorkItemCompletedCallback()
|
||||
if (decrementWorkItemsInStpQueue)
|
||||
{
|
||||
--_workItemsInStpQueue;
|
||||
private void EnqueueToSTPNextWorkItem(WorkItem workItem, bool decrementWorkItemsInStpQueue)
|
||||
{
|
||||
lock(_lock)
|
||||
{
|
||||
// Got here from OnWorkItemCompletedCallback()
|
||||
if (decrementWorkItemsInStpQueue)
|
||||
{
|
||||
--_workItemsInStpQueue;
|
||||
|
||||
if(_workItemsInStpQueue < 0)
|
||||
{
|
||||
_workItemsInStpQueue = 0;
|
||||
}
|
||||
if(_workItemsInStpQueue < 0)
|
||||
{
|
||||
_workItemsInStpQueue = 0;
|
||||
}
|
||||
|
||||
--_workItemsExecutingInStp;
|
||||
--_workItemsExecutingInStp;
|
||||
|
||||
if(_workItemsExecutingInStp < 0)
|
||||
{
|
||||
_workItemsExecutingInStp = 0;
|
||||
}
|
||||
}
|
||||
if(_workItemsExecutingInStp < 0)
|
||||
{
|
||||
_workItemsExecutingInStp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// If the work item is not null then enqueue it
|
||||
if (null != workItem)
|
||||
{
|
||||
workItem.CanceledWorkItemsGroup = _canceledWorkItemsGroup;
|
||||
// If the work item is not null then enqueue it
|
||||
if (null != workItem)
|
||||
{
|
||||
workItem.CanceledWorkItemsGroup = _canceledWorkItemsGroup;
|
||||
|
||||
RegisterToWorkItemCompletion(workItem.GetWorkItemResult());
|
||||
_workItemsQueue.Enqueue(workItem);
|
||||
//_stp.IncrementWorkItemsCount();
|
||||
RegisterToWorkItemCompletion(workItem.GetWorkItemResult());
|
||||
_workItemsQueue.Enqueue(workItem);
|
||||
//_stp.IncrementWorkItemsCount();
|
||||
|
||||
if ((1 == _workItemsQueue.Count) &&
|
||||
(0 == _workItemsInStpQueue))
|
||||
{
|
||||
_stp.RegisterWorkItemsGroup(this);
|
||||
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);
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_isSuspended)
|
||||
{
|
||||
if (_workItemsInStpQueue < _concurrency)
|
||||
{
|
||||
WorkItem nextWorkItem = _workItemsQueue.Dequeue() as WorkItem;
|
||||
{
|
||||
if (_workItemsInStpQueue < _concurrency)
|
||||
{
|
||||
WorkItem nextWorkItem = _workItemsQueue.Dequeue() as WorkItem;
|
||||
try
|
||||
{
|
||||
_stp.Enqueue(nextWorkItem);
|
||||
@@ -348,14 +348,14 @@ namespace Amib.Threading.Internal
|
||||
// The STP has been shutdown
|
||||
}
|
||||
|
||||
++_workItemsInStpQueue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
++_workItemsInStpQueue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
|
||||
14
ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs
vendored
14
ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs
vendored
@@ -132,7 +132,7 @@ namespace Amib.Threading.Internal
|
||||
/// </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.
|
||||
/// 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)
|
||||
@@ -147,7 +147,7 @@ namespace Amib.Threading.Internal
|
||||
/// </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.
|
||||
/// 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>
|
||||
@@ -165,7 +165,7 @@ namespace Amib.Threading.Internal
|
||||
/// <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.
|
||||
/// 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)
|
||||
@@ -181,7 +181,7 @@ namespace Amib.Threading.Internal
|
||||
/// </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.
|
||||
/// 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
|
||||
@@ -203,7 +203,7 @@ namespace Amib.Threading.Internal
|
||||
/// </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.
|
||||
/// 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
|
||||
@@ -227,7 +227,7 @@ namespace Amib.Threading.Internal
|
||||
/// </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.
|
||||
/// 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
|
||||
@@ -251,7 +251,7 @@ namespace Amib.Threading.Internal
|
||||
/// </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.
|
||||
/// 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
|
||||
|
||||
770
ThirdParty/SmartThreadPool/WorkItemsQueue.cs
vendored
770
ThirdParty/SmartThreadPool/WorkItemsQueue.cs
vendored
@@ -4,29 +4,29 @@ using System.Threading;
|
||||
|
||||
namespace Amib.Threading.Internal
|
||||
{
|
||||
#region WorkItemsQueue class
|
||||
#region WorkItemsQueue class
|
||||
|
||||
/// <summary>
|
||||
/// WorkItemsQueue class.
|
||||
/// </summary>
|
||||
public class WorkItemsQueue : IDisposable
|
||||
{
|
||||
#region Member variables
|
||||
/// <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 queue (implemented as stack).
|
||||
/// </summary>
|
||||
private readonly WaiterEntry _headWaiterEntry = new WaiterEntry();
|
||||
|
||||
/// <summary>
|
||||
/// Waiters count
|
||||
/// </summary>
|
||||
private int _waitersCount = 0;
|
||||
/// <summary>
|
||||
/// Waiters count
|
||||
/// </summary>
|
||||
private int _waitersCount = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Work items queue
|
||||
/// </summary>
|
||||
private readonly PriorityQueue _workItems = new PriorityQueue();
|
||||
/// <summary>
|
||||
/// Work items queue
|
||||
/// </summary>
|
||||
private readonly PriorityQueue _workItems = new PriorityQueue();
|
||||
|
||||
/// <summary>
|
||||
/// Indicate that work items are allowed to be queued
|
||||
@@ -34,7 +34,7 @@ namespace Amib.Threading.Internal
|
||||
private bool _isWorkItemsQueueActive = true;
|
||||
|
||||
|
||||
#if (WINDOWS_PHONE)
|
||||
#if (WINDOWS_PHONE)
|
||||
private static readonly Dictionary<int, WaiterEntry> _waiterEntries = new Dictionary<int, WaiterEntry>();
|
||||
#elif (_WINDOWS_CE)
|
||||
private static LocalDataStoreSlot _waiterEntrySlot = Thread.AllocateDataSlot();
|
||||
@@ -50,7 +50,7 @@ namespace Amib.Threading.Internal
|
||||
/// </summary>
|
||||
private static WaiterEntry CurrentWaiterEntry
|
||||
{
|
||||
#if (WINDOWS_PHONE)
|
||||
#if (WINDOWS_PHONE)
|
||||
get
|
||||
{
|
||||
lock (_waiterEntries)
|
||||
@@ -92,60 +92,60 @@ namespace Amib.Threading.Internal
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A flag that indicates if the WorkItemsQueue has been disposed.
|
||||
/// </summary>
|
||||
/// A flag that indicates if the WorkItemsQueue has been disposed.
|
||||
/// </summary>
|
||||
private bool _isDisposed = false;
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
#region Public properties
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current number of work items in the queue
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
return _workItems.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current number of waiters
|
||||
/// </summary>
|
||||
public int WaitersCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return _waitersCount;
|
||||
}
|
||||
}
|
||||
/// <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");
|
||||
}
|
||||
/// <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;
|
||||
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)
|
||||
{
|
||||
// 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)
|
||||
@@ -153,55 +153,55 @@ namespace Amib.Threading.Internal
|
||||
return false;
|
||||
}
|
||||
|
||||
while(_waitersCount > 0)
|
||||
{
|
||||
// Dequeue a waiter.
|
||||
WaiterEntry waiterEntry = PopWaiter();
|
||||
while(_waitersCount > 0)
|
||||
{
|
||||
// Dequeue a waiter.
|
||||
WaiterEntry waiterEntry = PopWaiter();
|
||||
|
||||
// Signal the waiter. On success break the loop
|
||||
if (waiterEntry.Signal(workItem))
|
||||
{
|
||||
enqueue = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Signal the waiter. On success break the loop
|
||||
if (waiterEntry.Signal(workItem))
|
||||
{
|
||||
enqueue = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (enqueue)
|
||||
{
|
||||
// Enqueue the work item
|
||||
_workItems.Enqueue(workItem);
|
||||
}
|
||||
}
|
||||
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.
|
||||
/// <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)
|
||||
{
|
||||
WaiterEntry waiterEntry;
|
||||
WorkItem workItem = null;
|
||||
lock (this)
|
||||
{
|
||||
ValidateNotDisposed();
|
||||
|
||||
// If there are waiting work items then take one and return.
|
||||
@@ -218,68 +218,68 @@ namespace Amib.Threading.Internal
|
||||
|
||||
// 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 };
|
||||
// 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.
|
||||
// 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.
|
||||
// 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);
|
||||
waitHandles,
|
||||
millisecondsTimeout,
|
||||
true);
|
||||
|
||||
lock(this)
|
||||
{
|
||||
// success is true if it got a work item.
|
||||
bool success = (0 == index);
|
||||
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;
|
||||
// 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 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);
|
||||
}
|
||||
// On timeout remove the waiter from the queue.
|
||||
// Note that the complexity is O(1).
|
||||
if(timeout)
|
||||
{
|
||||
RemoveWaiter(waiterEntry, false);
|
||||
}
|
||||
|
||||
// Again readability
|
||||
success = !timeout;
|
||||
}
|
||||
// Again readability
|
||||
success = !timeout;
|
||||
}
|
||||
|
||||
// On success return the work item
|
||||
if (success)
|
||||
{
|
||||
workItem = waiterEntry.WorkItem;
|
||||
// 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;
|
||||
}
|
||||
if (null == workItem)
|
||||
{
|
||||
workItem = _workItems.Dequeue() as WorkItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
// On failure return null.
|
||||
return workItem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleanup the work items queue, hence no more work
|
||||
/// Cleanup the work items queue, hence no more work
|
||||
/// items are allowed to be queue
|
||||
/// </summary>
|
||||
private void Cleanup()
|
||||
@@ -303,19 +303,19 @@ namespace Amib.Threading.Internal
|
||||
// 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
|
||||
// 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();
|
||||
}
|
||||
while(_waitersCount > 0)
|
||||
{
|
||||
WaiterEntry waiterEntry = PopWaiter();
|
||||
waiterEntry.Timeout();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,275 +334,275 @@ namespace Amib.Threading.Internal
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
#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;
|
||||
}
|
||||
/// <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
|
||||
#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);
|
||||
/// <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 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;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
_headWaiterEntry._nextWaiterEntry = newWaiterEntry;
|
||||
newWaiterEntry._nextWaiterEntry = oldFirstWaiterEntry;
|
||||
newWaiterEntry._prevWaiterEntry = _headWaiterEntry;
|
||||
oldFirstWaiterEntry._prevWaiterEntry = newWaiterEntry;
|
||||
}
|
||||
|
||||
// Increment the number of waiters
|
||||
++_waitersCount;
|
||||
}
|
||||
// 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;
|
||||
/// <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;
|
||||
// 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 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;
|
||||
}
|
||||
// Update the new stack head
|
||||
_headWaiterEntry._nextWaiterEntry = newHeadWaiterEntry;
|
||||
if (null != newHeadWaiterEntry)
|
||||
{
|
||||
newHeadWaiterEntry._prevWaiterEntry = _headWaiterEntry;
|
||||
}
|
||||
|
||||
// Return the old stack head
|
||||
return oldFirstWaiterEntry;
|
||||
}
|
||||
// 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;
|
||||
/// <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;
|
||||
// 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;
|
||||
// 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;
|
||||
// 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 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;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
// Decrement the waiters count if needed
|
||||
if (decrementCounter)
|
||||
{
|
||||
--_waitersCount;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region WaiterEntry class
|
||||
#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;
|
||||
// A waiter entry in the _waiters queue.
|
||||
public sealed class WaiterEntry : IDisposable
|
||||
{
|
||||
#region Member variables
|
||||
|
||||
/// <summary>
|
||||
/// A work item that passed directly to the waiter withou going
|
||||
/// 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 WorkItem _workItem = null;
|
||||
|
||||
private bool _isDisposed = false;
|
||||
|
||||
// Linked list members
|
||||
internal WaiterEntry _nextWaiterEntry = null;
|
||||
internal WaiterEntry _prevWaiterEntry = null;
|
||||
// Linked list members
|
||||
internal WaiterEntry _nextWaiterEntry = null;
|
||||
internal WaiterEntry _prevWaiterEntry = null;
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Construction
|
||||
#region Construction
|
||||
|
||||
public WaiterEntry()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
#endregion
|
||||
public WaiterEntry()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
#region Public methods
|
||||
#endregion
|
||||
|
||||
public WaitHandle WaitHandle
|
||||
{
|
||||
get { return _waitHandle; }
|
||||
}
|
||||
#region Public methods
|
||||
|
||||
public WorkItem WorkItem
|
||||
{
|
||||
get
|
||||
{
|
||||
return _workItem;
|
||||
}
|
||||
}
|
||||
public WaitHandle WaitHandle
|
||||
{
|
||||
get { return _waitHandle; }
|
||||
}
|
||||
|
||||
/// <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;
|
||||
}
|
||||
public WorkItem WorkItem
|
||||
{
|
||||
get
|
||||
{
|
||||
return _workItem;
|
||||
}
|
||||
}
|
||||
|
||||
/// <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
|
||||
/// <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;
|
||||
}
|
||||
_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>
|
||||
/// 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;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Free resources
|
||||
/// </summary>
|
||||
public void Close()
|
||||
{
|
||||
if (null != _waitHandle)
|
||||
{
|
||||
_waitHandle.Close();
|
||||
_waitHandle = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region IDisposable Members
|
||||
#region IDisposable Members
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
public void Dispose()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (!_isDisposed)
|
||||
@@ -613,10 +613,10 @@ namespace Amib.Threading.Internal
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
@@ -625,7 +625,7 @@ namespace Amib.Threading.Internal
|
||||
if (!_isDisposed)
|
||||
{
|
||||
Cleanup();
|
||||
_headWaiterEntry.Close();
|
||||
_headWaiterEntry.Close();
|
||||
}
|
||||
_isDisposed = true;
|
||||
}
|
||||
@@ -641,6 +641,6 @@ namespace Amib.Threading.Internal
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user