Exemplo n.º 1
0
        public void Dispatch()
        {
            IQueueReader reader = null;
            Item         item   = new Item();

            IQueueReader[] outstandingReaders = null;
            IQueueWaiter[] waiters            = null;
            bool           itemAvailable      = true;

            lock (ThisLock)
            {
                itemAvailable = !((_queueState == QueueState.Closed) || (_queueState == QueueState.Shutdown));
                GetWaiters(out waiters);

                if (_queueState != QueueState.Closed)
                {
                    _itemQueue.MakePendingItemAvailable();

                    if (_readerQueue.Count > 0)
                    {
                        item   = _itemQueue.DequeueAvailableItem();
                        reader = _readerQueue.Dequeue();

                        if (_queueState == QueueState.Shutdown && _readerQueue.Count > 0 && _itemQueue.ItemCount == 0)
                        {
                            outstandingReaders = new IQueueReader[_readerQueue.Count];
                            _readerQueue.CopyTo(outstandingReaders, 0);
                            _readerQueue.Clear();

                            itemAvailable = false;
                        }
                    }
                }
            }

            if (outstandingReaders != null)
            {
                if (s_completeOutstandingReadersCallback == null)
                {
                    s_completeOutstandingReadersCallback = CompleteOutstandingReadersCallback;
                }

                ActionItem.Schedule(s_completeOutstandingReadersCallback, outstandingReaders);
            }

            if (waiters != null)
            {
                CompleteWaitersLater(itemAvailable, waiters);
            }

            if (reader != null)
            {
                InvokeDequeuedCallback(item.DequeuedCallback);
                reader.Set(item);
            }
        }