Click here to Skip to main content
15,885,914 members
Articles / General Programming / Threads

Smart Thread Pool

Rate me:
Please Sign up or sign in to vote.
4.96/5 (314 votes)
27 Aug 2012Ms-PL40 min read 2.2M   29.1K   1.1K  
A .NET Thread Pool fully implemented in C# with many features.
// Ami Bar
// amibar@gmail.com

using System;
using System.Threading;

namespace Amib.Threading
{
	#region Delegates

	/// <summary>
	/// A delegate that represents the method to run as the work item
	/// </summary>
	/// <param name="state">A state object for the method to run</param>
	public delegate object WorkItemCallback(object state);

	/// <summary>
	/// A delegate to call after the WorkItemCallback completed
	/// </summary>
	/// <param name="wir">The work item result object</param>
	public delegate void PostExecuteWorkItemCallback(IWorkItemResult wir);

	/// <summary>
	/// A delegate to call when a WorkItemsGroup becomes idle
	/// </summary>
	/// <param name="workItemsGroup">A reference to the WorkItemsGroup that became idle</param>
	public delegate void WorkItemsGroupIdleHandler(IWorkItemsGroup workItemsGroup);

	#endregion

	#region WorkItem Priority

	public enum WorkItemPriority
	{
		Lowest,
		BelowNormal,
		Normal,
		AboveNormal,
		Highest,
	}

	#endregion

	#region IHasWorkItemPriority interface 

	public interface IHasWorkItemPriority
	{
		WorkItemPriority WorkItemPriority { get; }
	}

	#endregion

	#region IWorkItemsGroup interface 

	/// <summary>
	/// IWorkItemsGroup interface
	/// </summary>
	public interface IWorkItemsGroup
	{
		/// <summary>
		/// Get/Set the name of the WorkItemsGroup
		/// </summary>
		string Name { get; set; }

		IWorkItemResult QueueWorkItem(WorkItemCallback callback);
		IWorkItemResult QueueWorkItem(WorkItemCallback callback, WorkItemPriority workItemPriority);
		IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state);
		IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, WorkItemPriority workItemPriority);
		IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback);
		IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, WorkItemPriority workItemPriority);
		IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute);
		IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute, WorkItemPriority workItemPriority);

		IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback);
		IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state);

		void WaitForIdle();
		bool WaitForIdle(TimeSpan timeout);
		bool WaitForIdle(int millisecondsTimeout);

		int WaitingCallbacks { get; }
		event WorkItemsGroupIdleHandler OnIdle;

		void Cancel();
		void Start();
	}

	#endregion

	#region CallToPostExecute enumerator

	[Flags]
	public enum CallToPostExecute
	{
		Never                    = 0x00,
		WhenWorkItemCanceled     = 0x01,
		WhenWorkItemNotCanceled  = 0x02,
		Always                   = WhenWorkItemCanceled | WhenWorkItemNotCanceled,
	}

	#endregion

	#region IWorkItemResult interface

	/// <summary>
	/// IWorkItemResult interface
	/// </summary>
	public interface IWorkItemResult
	{
		/// <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>
		object 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
		object GetResult(
			int millisecondsTimeout,
			bool exitContext);

		/// <summary>
		/// Get the result of the work item.
		/// If the work item didn't run yet then the caller waits until timeout.
		/// </summary>
		/// <returns>The result of the work item</returns>
		/// On timeout throws WorkItemTimeoutException
		object 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
		object 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
		object 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>
		object 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="e">Filled with the exception if one was thrown</param>
		/// <returns>The result of the work item</returns>
		/// On timeout throws WorkItemTimeoutException
		object GetResult(
			int millisecondsTimeout,
			bool exitContext,
			out Exception e);

		/// <summary>
		/// Get the result of the work item.
		/// If the work item didn't run yet then the caller waits until timeout.
		/// </summary>
		/// <param name="e">Filled with the exception if one was thrown</param>
		/// <returns>The result of the work item</returns>
		/// On timeout throws WorkItemTimeoutException
		object 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
		object 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="e">Filled with the exception if one was thrown</param>
		/// On timeout throws WorkItemTimeoutException
		/// On cancel throws WorkItemCancelException
		object GetResult(			
			TimeSpan timeout,
			bool exitContext,
			WaitHandle cancelWaitHandle,
			out Exception e);

		/// <summary>
		/// Gets an indication whether the asynchronous operation has completed.
		/// </summary>
		bool IsCompleted { get; }

		/// <summary>
		/// Gets an indication whether the asynchronous operation has been canceled.
		/// </summary>
		bool IsCanceled { get; }

		/// <summary>
		/// Gets a user-defined object that qualifies or contains information about an asynchronous operation.
		/// </summary>
		object State { get; }

		/// <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>
		bool Cancel();

		/// <summary>
		/// Get the work item's priority
		/// </summary>
		WorkItemPriority WorkItemPriority { get; }

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

		/// <summary>
		/// Returns the exception if occured otherwise returns null.
		/// </summary>
		object Exception { get; }
	}

	#endregion
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


Written By
Software Developer (Senior)
Israel Israel
B.Sc. in Computer Science.
Works as Software Developer.

Comments and Discussions