public async Task Test()
        {
            // Explicitly defined descending order of priorities
            QueuePriority[] descendingPriorities =
            {
                QueuePriority.Higher,
                QueuePriority.Normal,
                QueuePriority.Lower
            };

            var pQueue = new PriorityQueueNotifierUC <QueuePriority, string>(descendingPriorities);

            pQueue.Enqueue(QueuePriority.Lower, "1Lower");
            pQueue.Enqueue(QueuePriority.Higher, "1Higher");
            pQueue.Enqueue(QueuePriority.Normal, "1Normal");

            pQueue.Enqueue(QueuePriority.Lower, "2Lower");
            pQueue.Enqueue(QueuePriority.Normal, "2Normal");
            pQueue.Enqueue(QueuePriority.Higher, "2Higher");

            pQueue.Enqueue(QueuePriority.Lower, "3Lower");
            pQueue.Enqueue(QueuePriority.Higher, "3Higher");
            pQueue.Enqueue(QueuePriority.Normal, "3Normal");

            await Task.Run(() => Descending(pQueue));
        }
        public async Task Test()
        {
            // Explicitly defined descending order of priorities
            QueuePriority[] descendingPriorities =
            {
                QueuePriority.Higher,
                QueuePriority.Normal,
                QueuePriority.Lower
            };

            var pQueue = new PriorityQueueNotifierUC <QueuePriority, string>(descendingPriorities);

            Task[] tasks =
            {
                Task.Run(() => Higher(pQueue)),
                Task.Run(() => Lower(pQueue)),
                Task.Run(() => Normal(pQueue))
            };

            //note: consumers will await enqueued data by producer(s) instead burning CPU cycles with TryDequeue on empty collection!!!

            pQueue.Enqueue(QueuePriority.Lower, "1Lower");
            pQueue.Enqueue(QueuePriority.Higher, "1Higher");
            pQueue.Enqueue(QueuePriority.Normal, "1Normal");

            pQueue.Enqueue(QueuePriority.Lower, "2Lower");
            pQueue.Enqueue(QueuePriority.Normal, "2Normal");
            pQueue.Enqueue(QueuePriority.Higher, "2Higher");

            pQueue.Enqueue(QueuePriority.Lower, "3Lower");
            pQueue.Enqueue(QueuePriority.Higher, "3Higher");
            pQueue.Enqueue(QueuePriority.Normal, "3Normal");

            await Task.WhenAll(tasks);
        }
        public async Task BasicFunctionality()
        {
            PriorityQueueNotifierUC <Priorities, Priorities> priorityQueues =
                new PriorityQueueNotifierUC <Priorities, Priorities>(DescendingPriorityOrder)
            ;

            priorityQueues.Enqueue(Priorities.Bottom, Priorities.Bottom);
            priorityQueues.Enqueue(Priorities.Medium, Priorities.Medium);
            priorityQueues.Enqueue(Priorities.Top, Priorities.Top);
            priorityQueues.Enqueue(Priorities.Bottom, Priorities.Bottom);
            priorityQueues.Enqueue(Priorities.Medium, Priorities.Medium);
            priorityQueues.Enqueue(Priorities.Top, Priorities.Top);
            priorityQueues.Enqueue(Priorities.Medium, Priorities.Medium);
            priorityQueues.Enqueue(Priorities.Top, Priorities.Top);

            Queue <Priorities> dequeue = new Queue <Priorities>();

            await TestNotification(priorityQueues, dequeue);

            Assert.AreEqual(dequeue.Dequeue(), Priorities.Top);
            Assert.AreEqual(dequeue.Dequeue(), Priorities.Top);
            Assert.AreEqual(dequeue.Dequeue(), Priorities.Top);
            Assert.AreEqual(dequeue.Dequeue(), Priorities.Medium);
            Assert.AreEqual(dequeue.Dequeue(), Priorities.Medium);
            Assert.AreEqual(dequeue.Dequeue(), Priorities.Medium);
            Assert.AreEqual(dequeue.Dequeue(), Priorities.Bottom);
            Assert.AreEqual(dequeue.Dequeue(), Priorities.Bottom);

            Assert.AreEqual(priorityQueues.Count(), 0);
            priorityQueues.Enqueue(Priorities.Medium, Priorities.Medium);
            Assert.AreEqual(priorityQueues.Count(), 1);

            Assert.AreEqual(priorityQueues.Count(Priorities.Top), 0);
            Assert.AreEqual(priorityQueues.Count(Priorities.Medium), 1);
            Assert.AreEqual(priorityQueues.Count(Priorities.Bottom), 0);

            await TestNotification(priorityQueues, dequeue);

            Assert.AreEqual(dequeue.Dequeue(), Priorities.Medium);
        }
        public void BasicFunctionality()
        {
            Priorities[] descendingPriorityOrder =
            {
                Priorities.Top,
                Priorities.Medium,
                Priorities.Bottom
            };

            PriorityQueueUC <Priorities, Priorities> priorityQueues =
                new PriorityQueueNotifierUC <Priorities, Priorities>(descendingPriorityOrder)
            ;

            priorityQueues.Enqueue(Priorities.Bottom, Priorities.Bottom);
            priorityQueues.Enqueue(Priorities.Medium, Priorities.Medium);
            priorityQueues.Enqueue(Priorities.Medium, Priorities.Medium);
            priorityQueues.Enqueue(Priorities.Medium, Priorities.Medium);
            priorityQueues.Enqueue(Priorities.Top, Priorities.Top);

            Priorities item;

            Assert.IsTrue(priorityQueues.TryDequeu(out item));
            Assert.AreEqual(item, Priorities.Top);

            Assert.IsTrue(priorityQueues.TryDequeu(out item));
            Assert.AreEqual(item, Priorities.Medium);

            Assert.IsTrue(priorityQueues.TryDequeu(out item));
            Assert.AreEqual(item, Priorities.Medium);

            Assert.IsTrue(priorityQueues.TryDequeu(out item));
            Assert.AreEqual(item, Priorities.Medium);

            Assert.IsTrue(priorityQueues.TryDequeu(out item));
            Assert.AreEqual(item, Priorities.Bottom);


            Assert.AreEqual(priorityQueues.Count(), 0);

            priorityQueues.Enqueue(Priorities.Medium, Priorities.Medium);
            Assert.AreEqual(priorityQueues.Count(Priorities.Top), 0);
            Assert.AreEqual(priorityQueues.Count(Priorities.Medium), 1);
            Assert.AreEqual(priorityQueues.Count(Priorities.Bottom), 0);
        }