/// <summary> /// Dequeue work from the work queue. /// </summary> /// <param name="timeoutMilliSeconds">Maximum time to wait for.</param> /// <param name="cancelHandle">Wait handle which can be signaled when all waiting threads should stop /// waiting for work.</param> /// <returns>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">Wait handle which can be signaled when all waiting threads should stop /// waiting for work.</param> /// <returns>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; }