📄 smartthreadpool.cs
字号:
/// <summary>
/// Empties the queue of work items and abort the threads in the pool.
/// </summary>
public void Shutdown(bool forceAbort, int millisecondsTimeout)
{
ValidateNotDisposed();
ISTPInstancePerformanceCounters pcs = _pcs;
if (NullSTPInstancePerformanceCounters.Instance != _pcs)
{
_pcs.Dispose();
// Set the _pcs to "null" to stop updating the performance
// counters
_pcs = NullSTPInstancePerformanceCounters.Instance;
}
Thread [] threads = null;
lock(_workerThreads.SyncRoot)
{
// Shutdown the work items queue
_workItemsQueue.Dispose();
// Signal the threads to exit
_shutdown = true;
_shuttingDownEvent.Set();
// Make a copy of the threads' references in the pool
threads = new Thread [_workerThreads.Count];
_workerThreads.Keys.CopyTo(threads, 0);
}
int millisecondsLeft = millisecondsTimeout;
DateTime start = DateTime.Now;
bool waitInfinitely = (Timeout.Infinite == millisecondsTimeout);
bool timeout = false;
// Each iteration we update the time left for the timeout.
foreach(Thread thread in threads)
{
// Join don't work with negative numbers
if (!waitInfinitely && (millisecondsLeft < 0))
{
timeout = true;
break;
}
// Wait for the thread to terminate
bool success = thread.Join(millisecondsLeft);
if(!success)
{
timeout = true;
break;
}
if(!waitInfinitely)
{
// Update the time left to wait
TimeSpan ts = DateTime.Now - start;
millisecondsLeft = millisecondsTimeout - (int)ts.TotalMilliseconds;
}
}
if (timeout && forceAbort)
{
// Abort the threads in the pool
foreach(Thread thread in threads)
{
if ((thread != null) && thread.IsAlive)
{
try
{
thread.Abort("Shutdown");
}
catch(SecurityException e)
{
e.GetHashCode();
}
catch(ThreadStateException ex)
{
ex.GetHashCode();
// In case the thread has been terminated
// after the check if it is alive.
}
}
}
}
// Dispose of the performance counters
pcs.Dispose();
}
/// <summary>
/// Wait for all work items to complete
/// </summary>
/// <param name="workItemResults">Array of work item result objects</param>
/// <returns>
/// true when every work item in workItemResults has completed; otherwise false.
/// </returns>
public static bool WaitAll(
IWorkItemResult [] workItemResults)
{
return WaitAll(workItemResults, Timeout.Infinite, true);
}
/// <summary>
/// Wait for all work items to complete
/// </summary>
/// <param name="workItemResults">Array of work item result objects</param>
/// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param>
/// <param name="exitContext">
/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
/// </param>
/// <returns>
/// true when every work item in workItemResults has completed; otherwise false.
/// </returns>
public static bool WaitAll(
IWorkItemResult [] workItemResults,
TimeSpan timeout,
bool exitContext)
{
return WaitAll(workItemResults, (int)timeout.TotalMilliseconds, exitContext);
}
/// <summary>
/// Wait for all work items to complete
/// </summary>
/// <param name="workItemResults">Array of work item result objects</param>
/// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param>
/// <param name="exitContext">
/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
/// </param>
/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
/// <returns>
/// true when every work item in workItemResults has completed; otherwise false.
/// </returns>
public static bool WaitAll(
IWorkItemResult [] workItemResults,
TimeSpan timeout,
bool exitContext,
WaitHandle cancelWaitHandle)
{
return WaitAll(workItemResults, (int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle);
}
/// <summary>
/// Wait for all work items to complete
/// </summary>
/// <param name="workItemResults">Array of work item result objects</param>
/// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
/// <param name="exitContext">
/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
/// </param>
/// <returns>
/// true when every work item in workItemResults has completed; otherwise false.
/// </returns>
public static bool WaitAll(
IWorkItemResult [] workItemResults,
int millisecondsTimeout,
bool exitContext)
{
return WorkItem.WaitAll(workItemResults, millisecondsTimeout, exitContext, null);
}
/// <summary>
/// Wait for all work items to complete
/// </summary>
/// <param name="workItemResults">Array of work item result objects</param>
/// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
/// <param name="exitContext">
/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
/// </param>
/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
/// <returns>
/// true when every work item in workItemResults has completed; otherwise false.
/// </returns>
public static bool WaitAll(
IWorkItemResult [] workItemResults,
int millisecondsTimeout,
bool exitContext,
WaitHandle cancelWaitHandle)
{
return WorkItem.WaitAll(workItemResults, millisecondsTimeout, exitContext, cancelWaitHandle);
}
/// <summary>
/// Waits for any of the work items in the specified array to complete, cancel, or timeout
/// </summary>
/// <param name="workItemResults">Array of work item result objects</param>
/// <returns>
/// The array index of the work item result that satisfied the wait, or WaitTimeout if any of the work items has been canceled.
/// </returns>
public static int WaitAny(
IWorkItemResult [] workItemResults)
{
return WaitAny(workItemResults, Timeout.Infinite, true);
}
/// <summary>
/// Waits for any of the work items in the specified array to complete, cancel, or timeout
/// </summary>
/// <param name="workItemResults">Array of work item result objects</param>
/// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param>
/// <param name="exitContext">
/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
/// </param>
/// <returns>
/// The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled.
/// </returns>
public static int WaitAny(
IWorkItemResult [] workItemResults,
TimeSpan timeout,
bool exitContext)
{
return WaitAny(workItemResults, (int)timeout.TotalMilliseconds, exitContext);
}
/// <summary>
/// Waits for any of the work items in the specified array to complete, cancel, or timeout
/// </summary>
/// <param name="workItemResults">Array of work item result objects</param>
/// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param>
/// <param name="exitContext">
/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
/// </param>
/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
/// <returns>
/// The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled.
/// </returns>
public static int WaitAny(
IWorkItemResult [] workItemResults,
TimeSpan timeout,
bool exitContext,
WaitHandle cancelWaitHandle)
{
return WaitAny(workItemResults, (int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle);
}
/// <summary>
/// Waits for any of the work items in the specified array to complete, cancel, or timeout
/// </summary>
/// <param name="workItemResults">Array of work item result objects</param>
/// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
/// <param name="exitContext">
/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
/// </param>
/// <returns>
/// The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled.
/// </returns>
public static int WaitAny(
IWorkItemResult [] workItemResults,
int millisecondsTimeout,
bool exitContext)
{
return WorkItem.WaitAny(workItemResults, millisecondsTimeout, exitContext, null);
}
/// <summary>
/// Waits for any of the work items in the specified array to complete, cancel, or timeout
/// </summary>
/// <param name="workItemResults">Array of work item result objects</param>
/// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
/// <param name="exitContext">
/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
/// </param>
/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
/// <returns>
/// The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled.
/// </returns>
public static int WaitAny(
IWorkItemResult [] workItemResults,
int millisecondsTimeout,
bool exitContext,
WaitHandle cancelWaitHandle)
{
return WorkItem.WaitAny(workItemResults, millisecondsTimeout, exitContext, cancelWaitHandle);
}
public IWorkItemsGroup CreateWorkItemsGroup(int concurrency)
{
IWorkItemsGroup workItemsGroup = new WorkItemsGroup(this, concurrency, _stpStartInfo);
return workItemsGroup;
}
public IWorkItemsGroup CreateWorkItemsGroup(int concurrency, WIGStartInfo wigStartInfo)
{
IWorkItemsGroup workItemsGroup = new WorkItemsGroup(this, concurrency, wigStartInfo);
return workItemsGroup;
}
public event WorkItemsGroupIdleHandler OnIdle
{
add
{
throw new NotImplementedException("This event is not implemented in the SmartThreadPool class. Please create a WorkItemsGroup in order to use this feature.");
//_onIdle += value;
}
remove
{
throw new NotImplementedException("This event is not implemented in the SmartThreadPool class. Please create a WorkItemsGroup in order to use this feature.");
//_onIdle -= value;
}
}
public void Cancel()
{
ICollection workItemsGroups = _workItemsGroups.Values;
foreach(WorkItemsGroup workItemsGroup in workItemsGroups)
{
workItemsGroup.Cancel();
}
}
public void Start()
{
lock (this)
{
if (!this._stpStartInfo.StartSuspended)
{
return;
}
_stpStartInfo.StartSuspended = false;
}
ICollection workItemsGroups = _workItemsGroups.Values;
foreach(WorkItemsGroup workItemsGroup in workItemsGroups)
{
workItemsGroup.OnSTPIsStarting();
}
StartOptimalNumberOfThreads();
}
#endregion
#region Properties
/// <summary>
/// Get/Set the name of the SmartThreadPool instance
/// </summary>
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
/// <summary>
/// Get the lower limit of threads in the pool.
/// </summary>
public int MinThreads
{
get
{
ValidateNotDisposed();
return _stpStartInfo.MinWorkerThreads;
}
}
/// <summary>
/// Get the upper limit of threads in the pool.
/// </summary>
public int MaxThreads
{
get
{
ValidateNotDisposed();
return _stpStartInfo.MaxWorkerThreads;
}
}
/// <summary>
/// Get the number of threads in the thread pool.
/// Should be between the lower and the upper limits.
/// </summary>
public int ActiveThreads
{
get
{
ValidateNotDisposed();
return _workerThreads.Count;
}
}
/// <summary>
/// Get the number of busy (not idle) threads in the thread pool.
/// </summary>
public int InUseThreads
{
get
{
ValidateNotDisposed();
return _inUseWorkerThreads;
}
}
/// <summary>
/// Get the number of work items in the queue.
/// </summary>
public int WaitingCallbacks
{
get
{
ValidateNotDisposed();
return _workItemsQueue.Count;
}
}
public event EventHandler Idle
{
add
{
_stpIdle += value;
}
remove
{
_stpIdle -= value;
}
}
#endregion
#region IDisposable Members
~SmartThreadPool()
{
Dispose();
}
public void Dispose()
{
if (!_isDisposed)
{
if (!_shutdown)
{
Shutdown();
}
if (null != _shuttingDownEvent)
{
_shuttingDownEvent.Close();
_shuttingDownEvent = null;
}
_workerThreads.Clear();
_isDisposed = true;
GC.SuppressFinalize(this);
}
}
private void ValidateNotDisposed()
{
if(_isDisposed)
{
throw new ObjectDisposedException(GetType().ToString(), "The SmartThreadPool has been shutdown");
}
}
#endregion
}
#endregion
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -