[Adapdev-commits] Adapdev/src/Adapdev/Threading ThreadPoolWait.cs,NONE,1.1
Status: Beta
Brought to you by:
intesar66
From: Sean M. <int...@us...> - 2005-10-26 05:28:00
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev/Threading In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17136/src/Adapdev/Threading Added Files: ThreadPoolWait.cs Log Message: Added multi-threading support to testing engine --- NEW FILE: ThreadPoolWait.cs --- // Stephen Toub // st...@mi... // http://msdn.microsoft.com/msdnmag/issues/04/10/NETMatters/ using System; using System.Threading; using System.Collections; namespace Adapdev.Threading { /// <summary>ThreadPool utility class that allows for easily waiting on queued delegates.</summary> public class ThreadPoolWait : IDisposable { /// <summary>Number of items remaining to be executed.</summary> private int _remainingWorkItems = 1; /// <summary>Event that signals whether all items have been executed.</summary> private ManualResetEvent _done = new ManualResetEvent(false); /// <summary>Queues a user work item to the ThreadPool.</summary> /// <param name="callback">The work item to be queued.</param> public void QueueUserWorkItem(WaitCallback callback) { QueueUserWorkItem(callback, null); } /// <summary>Queues a user work item to the ThreadPool.</summary> /// <param name="callback">The work item to be queued.</param> /// <param name="state">State to be passed to the queued work item</param> public void QueueUserWorkItem(WaitCallback callback, object state) { ThrowIfDisposed(); QueuedCallback qc = new QueuedCallback(); qc.Callback = callback; qc.State = state; Interlocked.Increment(ref _remainingWorkItems); ThreadPool.QueueUserWorkItem(new WaitCallback(HandleWorkItem), qc); } /// <summary>Wait for all items to finish executing.</summary> public bool WaitOne() { return WaitOne(-1, false); } /// <summary>Wait for all items to finish executing.</summary> public bool WaitOne(TimeSpan timeout, bool exitContext) { return WaitOne((int)timeout.TotalMilliseconds, exitContext); } /// <summary>Wait for all items to finish executing.</summary> public bool WaitOne(int millisecondsTimeout, bool exitContext) { ThrowIfDisposed(); DoneWorkItem(); bool rv = _done.WaitOne(millisecondsTimeout, exitContext); // If the event is set, then we'll return true, but first // reset so that this instance can be used again. If the // event isn't set, put back the 1 unit removed by calling // DoneWorkItem. The next time WaitOne is called, // this unit will be removed by the call to DoneWorkItem. if (rv) { _remainingWorkItems = 1; _done.Reset(); } else Interlocked.Increment(ref _remainingWorkItems); return rv; } /// <summary>Executes the callback passed as state and signals its completion when it has finished executing.</summary> /// <param name="state"></param> private void HandleWorkItem(object state) { QueuedCallback qc = (QueuedCallback)state; try { qc.Callback(qc.State); } finally { DoneWorkItem(); } } /// <summary>Decrements the number of remaining items, signaling the ManualResetEvent if 0 are left.</summary> private void DoneWorkItem() { if (Interlocked.Decrement(ref _remainingWorkItems) == 0) _done.Set(); } /// <summary>State class that wraps a WaitCallback and the state object to be passed to it.</summary> private class QueuedCallback { /// <summary>A callback delegate queued to the ThreadPool.</summary> public WaitCallback Callback; /// <summary>The state to be passed to the callback.</summary> public object State; } /// <summary>Throws an exception if this instance has already been disposed.</summary> private void ThrowIfDisposed() { if (_done == null) throw new ObjectDisposedException(GetType().Name); } /// <summary>Disposes this ThreadPoolWait.</summary> public void Dispose() { if (_done != null) { ((IDisposable)_done).Dispose(); _done = null; } } } } |