Beispiel #1
0
        public void OrderedQueueTest()
        {
            var q = new OrderingQueue<string>();

            q.Enqueue(0, "Zero");
            Assert.True(q.CanDequeue);
            Assert.AreEqual("Zero",q.Dequeue());

            q.Enqueue(2, "Two");
            Assert.False(q.CanDequeue);

            q.Enqueue(3, "Three");
            Assert.False(q.CanDequeue);

            q.Enqueue(1, "One");
            Assert.True(q.CanDequeue);
            Assert.AreEqual("One",q.Dequeue());
            Assert.True(q.CanDequeue);
            Assert.AreEqual("Two",q.Dequeue());
            Assert.True(q.CanDequeue);
            Assert.AreEqual("Three",q.Dequeue());
            Assert.False(q.CanDequeue);
        }
Beispiel #2
0
        /// <summary>
        /// Get the next piece of the compressed file
        /// </summary>
        /// <returns>Packet containing part of the compressed file, or null, if file is ended</returns>
        /// <param name="cancel">Cancellation flag</param>
        public FilePacketMemoryStream Consume(out bool cancel)
        {
            FilePacketMemoryStream result = null;

            var taken = true;

            mutex.WaitOne();
            try
            {
                cancel = cancelled;
                if (cancel)
                {
                    return(result); // Пустой результат.
                }
                var eventType = EventsForConsumer.PacketsExists;
                // If queue is empty, begin to await when it's filled
                while (queue.CountContiguous == 0 && activeCompressorThreads != 0)
                {
                    taken = false;
                    mutex.ReleaseMutex();

                    eventType = (EventsForConsumer)WaitHandle.WaitAny(eventsForConsumer);
                    mutex.WaitOne();
                    taken = true;

                    if ((eventType == EventsForConsumer.PacketAppeared && queue.CountContiguous != 0) ||
                        eventType == EventsForConsumer.ProductionCompleted ||
                        eventType == EventsForConsumer.Cancel)
                    {
                        break;
                    }
                }

                // If queue is empty and all compressor threads finished their work, we are finishing our work too
                if (queue.CountContiguous == 0 && activeCompressorThreads == 0)
                {
                    return(result); // Empty result
                }
                switch (eventType)
                {
                case EventsForConsumer.PacketsExists:
                case EventsForConsumer.PacketAppeared:
                    var hasSpace = queue.HaveSpace();
                    result = queue.Dequeue();
                    if (!hasSpace && queue.HaveSpace())     // If one new free space appeared in the queue, send signal to the producer
                    {
                        eventForNewSpaceInQueue.Set();
                    }
                    if (eventType == EventsForConsumer.PacketAppeared && queue.CountContiguous == 0)
                    {
                        eventForFirstPacketInQueue.Reset();     // Resetting our signal about packet appearing
                    }
                    break;

                case EventsForConsumer.ProductionCompleted:
                    // Do nothing, just returning the pre-initialized empty result below
                    break;

                case EventsForConsumer.Cancel:
                    cancel = true;
                    break;

                default:
                    Debug.Write($"Unsupported event type for consumer: {Enum.GetName(typeof(EventsForConsumer), eventType)}");
                    break;
                }
            }
            finally
            {
                if (taken)
                {
                    mutex.ReleaseMutex();
                }
            }

            return(result);
        }