/// <summary> /// Dequeue work from the work queue /// </summary> /// <param name="timeoutMilliSeconds">maximum time to wait for </param> /// <param name="cancelHandle"></param> /// <returns>IWork work to process</returns> public IWork Dequeue(int timeoutMilliSeconds, WaitHandle cancelHandle) { IWork work = null; lock (_queueMutex) { // if queue already contains items, return work immediately if (_queueItemCount > 0) { Queue <IWork> queue = GetFirstQueueWithWork(); if (queue != null) { work = queue.Dequeue(); _queueItemCount--; return(work); } } // block the call to this method for the current thread until we receive work, // or until the given timeout has been reached else { if (_workWaiter == null) { _workWaiter = new WorkWaiter(); } _workWaiter.Reset(); _workWaiters.Add(_workWaiter); } } // create array of waiters, and invoke waitany so we wait until any of the handles is signaled WaitHandle[] waiters = new WaitHandle[] { _workWaiter.WaitHandle, cancelHandle }; int i = WaitHandle.WaitAny(waiters, timeoutMilliSeconds, true); lock (_queueMutex) { // if first WaitHandle was signaled, then this means we received some work if (i == 0) { work = _workWaiter.Work; } else { // waiting has either been canceled, or timeout has been reached if (_workWaiters.Contains(_workWaiter)) { _workWaiters.Remove(_workWaiter); } } } return(work); }
public void Add(IWork work, QueuePriority priority) { lock (_queueMutex) { bool mustQueue = true; while (_workWaiters.Count > 0) { WorkWaiter waiter = _workWaiters[0]; _workWaiters.Remove(waiter); if (waiter.Signal(work)) { mustQueue = false; break; } } if (mustQueue) { Queue <IWork> queue = GetQueue(priority); queue.Enqueue(work); _queueItemCount++; } } }
/// <summary> /// Dequeue work from the work queue /// </summary> /// <param name="timeoutMilliSeconds">maximum time to wait for </param> /// <param name="cancelHandle"></param> /// <returns>IWork work to process</returns> public IWork Dequeue(int timeoutMilliSeconds, WaitHandle cancelHandle) { IWork work = null; lock (_queueMutex) { // if queue already contains items, return work immediately if (_queueItemCount > 0) { Queue<IWork> queue = GetFirstQueueWithWork(); if (queue != null) { work = queue.Dequeue(); _queueItemCount--; return work; } } // block the call to this method for the current thread until we receive work, // or until the given timeout has been reached else { if (_workWaiter == null) { _workWaiter = new WorkWaiter(); } _workWaiter.Reset(); _workWaiters.Add(_workWaiter); } } // create array of waiters, and invoke waitany so we wait until any of the handles is signaled WaitHandle[] waiters = new WaitHandle[] {_workWaiter.WaitHandle, cancelHandle}; int i = WaitHandle.WaitAny(waiters, timeoutMilliSeconds, true); lock (_queueMutex) { // if first WaitHandle was signaled, then this means we received some work if (i == 0) { work = _workWaiter.Work; } else { // waiting has either been canceled, or timeout has been reached if (_workWaiters.Contains(_workWaiter)) { _workWaiters.Remove(_workWaiter); } } } return work; }