예제 #1
0
        /// <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);
        }
예제 #2
0
 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++;
         }
     }
 }
예제 #3
0
 /// <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;
 }