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

📄 workitem.cs

📁 线程池实例,1.1版本,用于代替.net自带线程池
💻 CS
📖 第 1 页 / 共 2 页
字号:
				GetWaitHandles(workItemResults, waitHandles);
			}

			int result = WaitHandle.WaitAny(waitHandles, millisecondsTimeout, exitContext);

			// Treat cancel as timeout
			if (null != cancelWaitHandle)
			{
				if (result == workItemResults.Length)
				{
					result = WaitHandle.WaitTimeout;
				}
			}

			ReleaseWaitHandles(workItemResults);

			return result;
		}

		/// <summary>
		/// Fill an array of wait handles with the work items wait handles.
		/// </summary>
		/// <param name="workItemResults">An array of work item results</param>
		/// <param name="waitHandles">An array of wait handles to fill</param>
		private static void GetWaitHandles(
			IWorkItemResult [] workItemResults,
			WaitHandle [] waitHandles)
		{
			for(int i = 0; i < workItemResults.Length; ++i)
			{
				WorkItemResult wir = workItemResults[i] as WorkItemResult;
				Debug.Assert(null != wir, "All workItemResults must be WorkItemResult objects");

				waitHandles[i] = wir.GetWorkItem().GetWaitHandle();
			}
		}

		/// <summary>
		/// Release the work items' wait handles
		/// </summary>
		/// <param name="workItemResults">An array of work item results</param>
		private static void ReleaseWaitHandles(IWorkItemResult [] workItemResults)
		{
			for(int i = 0; i < workItemResults.Length; ++i)
			{
				WorkItemResult wir = workItemResults[i] as WorkItemResult;

				wir.GetWorkItem().ReleaseWaitHandle();
			}
		}


		#endregion
		
		#region Private Members

		private WorkItemState GetWorkItemState()
		{
			if (_canceledWorkItemsGroup.IsCanceled)
			{
				return WorkItemState.Canceled;
			}
			return _workItemState;

		}
		/// <summary>
		/// Sets the work item's state
		/// </summary>
		/// <param name="workItemState">The state to set the work item to</param>
		private void SetWorkItemState(WorkItemState workItemState)
		{
			lock(this)
			{
				_workItemState = workItemState;
			}
		}

		/// <summary>
		/// Signals that work item has been completed or canceled
		/// </summary>
		/// <param name="canceled">Indicates that the work item has been canceled</param>
		private void SignalComplete(bool canceled)
		{
			SetWorkItemState(canceled ? WorkItemState.Canceled : WorkItemState.Completed);
			lock(this)
			{
				// If someone is waiting then signal.
				if (null != _workItemCompleted)
				{
					_workItemCompleted.Set();
				}
			}
		}

		internal void WorkItemIsQueued()
		{
			_queuedTime = DateTime.Now;
		}

		#endregion
		
		#region Members exposed by WorkItemResult

		/// <summary>
		/// Cancel the work item if it didn't start running yet.
		/// </summary>
		/// <returns>Returns true on success or false if the work item is in progress or already completed</returns>
		private bool Cancel()
		{
			lock(this)
			{
				switch(GetWorkItemState())
				{
					case WorkItemState.Canceled:
						//Debug.WriteLine("Work item already canceled");
						return true;
					case WorkItemState.Completed:
					case WorkItemState.InProgress:
						//Debug.WriteLine("Work item cannot be canceled");
						return false;
					case WorkItemState.InQueue:
						// Signal to the wait for completion that the work
						// item has been completed (canceled). There is no
						// reason to wait for it to get out of the queue
						SignalComplete(true);
						//Debug.WriteLine("Work item canceled");
						return true;
				}
			}
			return false;
		}

		/// <summary>
		/// Get the result of the work item.
		/// If the work item didn't run yet then the caller waits for the result, timeout, or cancel.
		/// In case of error the method throws and exception
		/// </summary>
		/// <returns>The result of the work item</returns>
		private object GetResult(
			int millisecondsTimeout,
			bool exitContext,
			WaitHandle cancelWaitHandle)
		{
			Exception e = null;
			object result = GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e);
			if (null != e)
			{
				throw new WorkItemResultException("The work item caused an excpetion, see the inner exception for details", e);
			}
			return result;
		}

		/// <summary>
		/// Get the result of the work item.
		/// If the work item didn't run yet then the caller waits for the result, timeout, or cancel.
		/// In case of error the e argument is filled with the exception
		/// </summary>
		/// <returns>The result of the work item</returns>
		private object GetResult(
			int millisecondsTimeout,
			bool exitContext,
			WaitHandle cancelWaitHandle,
			out Exception e)
		{
			e = null;

			// Check for cancel
			if (WorkItemState.Canceled == GetWorkItemState())
			{
				throw new WorkItemCancelException("Work item canceled");
			}

			// Check for completion
			if (IsCompleted)
			{
				e = _exception;
				return _result;
			}

			// If no cancelWaitHandle is provided
			if (null == cancelWaitHandle)
			{
				WaitHandle wh = GetWaitHandle();

				bool timeout = !wh.WaitOne(millisecondsTimeout, exitContext);

				ReleaseWaitHandle();

				if (timeout)
				{
					throw new WorkItemTimeoutException("Work item timeout");
				}
			}
			else
			{
				WaitHandle wh = GetWaitHandle();
				int result = WaitHandle.WaitAny(new WaitHandle[] { wh, cancelWaitHandle });
				ReleaseWaitHandle();

				switch(result)
				{
					case 0:
						// The work item signaled
						// Note that the signal could be also as a result of canceling the 
						// work item (not the get result)
						break;
					case 1:
					case WaitHandle.WaitTimeout:
						throw new WorkItemTimeoutException("Work item timeout");
					default:
						Debug.Assert(false);
						break;

				}
			}

			// Check for cancel
			if (WorkItemState.Canceled == GetWorkItemState())
			{
				throw new WorkItemCancelException("Work item canceled");
			}

			Debug.Assert(IsCompleted);

			e = _exception;

			// Return the result
			return _result;
		}

		/// <summary>
		/// A wait handle to wait for completion, cancel, or timeout 
		/// </summary>
		private WaitHandle GetWaitHandle()
		{
			lock(this)
			{
				if (null == _workItemCompleted)
				{
					_workItemCompleted = new ManualResetEvent(IsCompleted);
				}
				++_workItemCompletedRefCount;
			}
			return _workItemCompleted;
		}

		private void ReleaseWaitHandle()
		{
			lock(this)
			{
				if (null != _workItemCompleted)
				{
					--_workItemCompletedRefCount;
					if (0 == _workItemCompletedRefCount)
					{
						_workItemCompleted.Close();
						_workItemCompleted = null;
					}
				}
			}
		}

		/// <summary>
		/// Returns true when the work item has completed or canceled
		/// </summary>
		private bool IsCompleted
		{
			get
			{
				lock(this)
				{
					WorkItemState workItemState = GetWorkItemState();
					return ((workItemState == WorkItemState.Completed) || 
							(workItemState == WorkItemState.Canceled));
				}
			}
		}

        /// <summary>
        /// Returns true when the work item has canceled
        /// </summary>
        public bool IsCanceled
        {
            get
            {
                lock(this)
                {
                    return (GetWorkItemState() == WorkItemState.Canceled);
                }
            }
        }

		#endregion

		#region IHasWorkItemPriority Members

		/// <summary>
		/// Returns the priority of the work item
		/// </summary>
		public WorkItemPriority WorkItemPriority
		{
			get
			{
				return _workItemInfo.WorkItemPriority;
			}
		}

		#endregion

		internal event WorkItemStateCallback OnWorkItemStarted
		{
			add
			{
				_workItemStartedEvent += value;
			}
			remove
			{
				_workItemStartedEvent -= value;
			}
		}

		internal event WorkItemStateCallback OnWorkItemCompleted
		{
			add
			{
				_workItemCompletedEvent += value;
			}
			remove
			{
				_workItemCompletedEvent -= value;
			}
		}


		#region WorkItemResult class

		private class WorkItemResult : IWorkItemResult, IInternalWorkItemResult
		{
			/// <summary>
			/// A back reference to the work item
			/// </summary>
			private WorkItem _workItem;

			public WorkItemResult(WorkItem workItem)
			{
				_workItem = workItem;
			}

			internal WorkItem GetWorkItem()
			{
				return _workItem;
			}

			#region IWorkItemResult Members

			public bool IsCompleted
			{
				get
				{
					return _workItem.IsCompleted;
				}
			}

            public bool IsCanceled
            {
                get
                {
                    return _workItem.IsCanceled;
                }
            }

			public object GetResult()
			{
				return _workItem.GetResult(Timeout.Infinite, true, null);
			}
	
			public object GetResult(int millisecondsTimeout, bool exitContext)
			{
				return _workItem.GetResult(millisecondsTimeout, exitContext, null);
			}

			public object GetResult(TimeSpan timeout, bool exitContext)
			{
				return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null);
			}

			public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle)
			{
				return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle);
			}

			public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle)
			{
				return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle);
			}

			public object GetResult(out Exception e)
			{
				return _workItem.GetResult(Timeout.Infinite, true, null, out e);
			}
	
			public object GetResult(int millisecondsTimeout, bool exitContext, out Exception e)
			{
				return _workItem.GetResult(millisecondsTimeout, exitContext, null, out e);
			}

			public object GetResult(TimeSpan timeout, bool exitContext, out Exception e)
			{
				return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null, out e);
			}

			public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
			{
				return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e);
			}

			public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
			{
				return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle, out e);
			}

			public bool Cancel()
			{
				return _workItem.Cancel();
			}

			public object State
			{
				get
				{
					return _workItem._state;
				}
			}

			public WorkItemPriority WorkItemPriority 
			{ 
				get
				{
					return _workItem._workItemInfo.WorkItemPriority;
				}
			}

			/// <summary>
			/// Return the result, same as GetResult()
			/// </summary>
			public object Result
			{
				get { return GetResult(); }
			}

			/// <summary>
			/// Returns the exception if occured otherwise returns null.
			/// This value is valid only after the work item completed,
			/// before that it is always null.
			/// </summary>
			public object Exception
			{
				get { return _workItem._exception; }
			}

			#endregion

			#region IInternalWorkItemResult Members

			public event WorkItemStateCallback OnWorkItemStarted
			{
				add
				{
					_workItem.OnWorkItemStarted += value;
				}
				remove
				{
					_workItem.OnWorkItemStarted -= value;
				}
			}


			public event WorkItemStateCallback OnWorkItemCompleted
			{
				add
				{
					_workItem.OnWorkItemCompleted += value;
				}
				remove
				{
					_workItem.OnWorkItemCompleted -= value;
				}
			}

			#endregion
		}

		#endregion

        public void DisposeOfState()
        {
			if (_workItemInfo.DisposeOfStateObjects)
			{
				IDisposable disp = _state as IDisposable;
				if (null != disp)
				{
					disp.Dispose();
					_state = null;
				}
			}
        }
    }
	#endregion
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -