Amib.Threading.Internal.WorkItemsQueue.DequeueWorkItem C# (CSharp) Метод

DequeueWorkItem() публичный Метод

Waits for a work item or exits on timeout or cancel
public DequeueWorkItem ( int millisecondsTimeout, WaitHandle cancelEvent ) : WorkItem
millisecondsTimeout int Timeout in milliseconds
cancelEvent System.Threading.WaitHandle Cancel wait handle
Результат WorkItem
        public WorkItem DequeueWorkItem(
            int millisecondsTimeout,
            WaitHandle cancelEvent)
        {
            /// This method cause the caller to wait for a work item.
            /// If there is at least one waiting work item then the
            /// method returns immidiately with true.
            ///
            /// If there are no waiting work items then the caller
            /// is queued between other waiters for a work item to arrive.
            ///
            /// If a work item didn't come within millisecondsTimeout or
            /// the user canceled the wait by signaling the cancelEvent
            /// then the method returns false to indicate that the caller
            /// didn't get a work item.

            WaiterEntry waiterEntry = null;
            WorkItem workItem = null;

            lock (this)
            {
                ValidateNotDisposed();

                // If there are waiting work items then take one and return.
                if (_workItems.Count > 0)
                {
                    workItem = _workItems.Dequeue() as WorkItem;
                    return workItem;
                }
                    // No waiting work items ...
                else
                {
                    // Get the wait entry for the waiters queue
                    waiterEntry = GetThreadWaiterEntry();

                    // Put the waiter with the other waiters
                    PushWaiter(waiterEntry);
                }
            }

            // Prepare array of wait handle for the WaitHandle.WaitAny()
            var waitHandles = new[]
                                  {
                                      waiterEntry.WaitHandle,
                                      cancelEvent
                                  };

            // Wait for an available resource, cancel event, or timeout.

            // During the wait we are supposes to exit the synchronization
            // domain. (Placing true as the third argument of the WaitAny())
            // It just doesn't work, I don't know why, so I have lock(this)
            // statments insted of one.

            int index = WaitHandle.WaitAny(
                waitHandles,
                millisecondsTimeout,
                true);

            lock (this)
            {
                // success is true if it got a work item.
                bool success = (0 == index);

                // The timeout variable is used only for readability.
                // (We treat cancel as timeout)
                bool timeout = !success;

                // On timeout update the waiterEntry that it is timed out
                if (timeout)
                {
                    // The Timeout() fails if the waiter has already been signaled
                    timeout = waiterEntry.Timeout();

                    // On timeout remove the waiter from the queue.
                    // Note that the complexity is O(1).
                    if (timeout)
                    {
                        RemoveWaiter(waiterEntry, false);
                    }

                    // Again readability
                    success = !timeout;
                }

                // On success return the work item
                if (success)
                {
                    workItem = waiterEntry.WorkItem;

                    if (null == workItem)
                    {
                        workItem = _workItems.Dequeue() as WorkItem;
                    }
                }
            }
            // On failure return null.
            return workItem;
        }