Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        /// <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();
                }
            }
        }
Ejemplo n.º 3
0
        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);
        }