⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smartthreadpool.cs

📁 线程池实例,1.1版本,用于代替.net自带线程池
💻 CS
📖 第 1 页 / 共 3 页
字号:

		/// <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 + -