/// <summary> /// Waits for a work item or exits on timeout or cancel /// </summary> /// <param name="millisecondsTimeout">Timeout in milliseconds</param> /// <param name="cancelEvent">Cancel wait handle</param> /// <returns>Returns true if the resource was granted</returns> public WorkItem DequeueWorkItem(int millisecondsTimeout, WaitHandle cancelEvent) { WaitEntry WaitEntry = null; WorkItem workItem = null; lock (this) { CheckDisposed(); // If there are waiting work items then take one and return. if (_workItems.Count > 0) { workItem = _workItems.Dequeue() as WorkItem; return(workItem); } else { // Get the wait entry for the waiters queue WaitEntry = GetThreadWaitEntry(); // Put the waiter with the other waiters PushWaitEntry(WaitEntry); } } // Prepare array of wait handle for the WaitHandle.WaitAny() WaitHandle [] waitHandles = new WaitHandle [] { WaitEntry.WaitHandle, cancelEvent }; // Wait for available resource, cancel event, or timeout. int index = WaitHandle.WaitAny(waitHandles, millisecondsTimeout, true); lock (this) { // Got a work item. bool success = (0 == index); // On timeout update the WaitEntry that it is timed out if (!success) { // The Timeout() fails if the waiter has already been signaled bool timeout = WaitEntry.Timeout(); // On timeout remove the WaitEntry from the queue. if (timeout) { RemoveWaiter(WaitEntry, false); } success = !timeout; } // On success return the work item if (success) { workItem = WaitEntry.WorkItem; if (workItem == null) { workItem = _workItems.Dequeue() as WorkItem; } } } return(workItem); }
/// <summary> /// Cleanup the work items queue, hence no more work items are allowed to be queued. /// </summary> private void Cleanup() { lock (this) { // Deactivate only once if (!_isWorkItemsQueueActive) { return; } // Don't queue more work items _isWorkItemsQueueActive = false; foreach (WorkItem workItem in _workItems) { workItem.DisposeState(); } // Clear the work items that are already queued _workItems.Clear(); while (_waitersCount > 0) { WaitEntry WaitEntry = PopWaiter(); WaitEntry.Timeout(); } } }
public WorkItem DequeueWorkItem(int millisecondsTimeout, WaitHandle cancelEvent) { WaitEntry newWaiterEntry = null; WorkItem workItem = null; WorkItemsQueue queue; lock ((queue = this)) { this.CheckDisposed(); if (this._workItems.Count > 0) { return(this._workItems.Dequeue() as WorkItem); } newWaiterEntry = this.GetThreadWaitEntry(); this.PushWaitEntry(newWaiterEntry); } WaitHandle[] waitHandles = new WaitHandle[] { newWaiterEntry.WaitHandle, cancelEvent }; int num = WaitHandle.WaitAny(waitHandles, millisecondsTimeout, true); lock ((queue = this)) { bool flag = 0 == num; if (!flag) { bool flag2 = newWaiterEntry.Timeout(); if (flag2) { this.RemoveWaiter(newWaiterEntry, false); } flag = !flag2; } if (flag) { workItem = newWaiterEntry.WorkItem; if (workItem == null) { workItem = this._workItems.Dequeue() as WorkItem; } } } return(workItem); }