private async Task Normal(PriorityQueueNotifierUC <QueuePriority, string> pQueue)
        {
            string dequeued;

            await pQueue.EnqueuedItemsAsync(QueuePriority.Normal);            //awaiting first not required, TryDequeue can come first as well

            //Overriding priority in while cycles with awaiting can come with CPU heavy costs
            //if TryDequeue priority and EnqueuedItemsAsync priority are different or one method takes default descending priorities and other not
            while (!pQueue.TryDequeu(out dequeued, QueuePriority.Normal))
            {
                await pQueue.EnqueuedItemsAsync(QueuePriority.Normal);
            }
            Assert.AreEqual("1Normal", dequeued);

            await pQueue.EnqueuedItemsAsync(QueuePriority.Normal);            //awaiting first not required, TryDequeue can come first as well

            //Overriding priority in while cycles with awaiting can come with CPU heavy costs
            //if TryDequeue priority and EnqueuedItemsAsync priority are different or one method takes default descending priorities and other not
            while (!pQueue.TryDequeu(out dequeued, QueuePriority.Normal))
            {
                await pQueue.EnqueuedItemsAsync(QueuePriority.Normal);
            }
            Assert.AreEqual("2Normal", dequeued);

            await pQueue.EnqueuedItemsAsync(QueuePriority.Normal);            //awaiting first not required, TryDequeue can come first as well

            //Overriding priority in while cycles with awaiting can come with CPU heavy costs
            //if TryDequeue priority and EnqueuedItemsAsync priority are different or one method takes default descending priorities and other not
            while (!pQueue.TryDequeu(out dequeued, QueuePriority.Normal))
            {
                await pQueue.EnqueuedItemsAsync(QueuePriority.Normal);
            }
            Assert.AreEqual("3Normal", dequeued);
        }
        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);
        }
        TestNotification(PriorityQueueNotifierUC <Priorities, Priorities> priorityQueues,
                         Queue <Priorities> dequeue)
        {
            while (priorityQueues.Count() > 0)
            {
                Priorities priorities;
                await priorityQueues.EnqueuedItemsAsync();

                if (!priorityQueues.TryDequeu(out priorities))
                {
                    continue;
                }
                dequeue.Enqueue(priorities);
            }
        }
        private async Task Descending(PriorityQueueNotifierUC <QueuePriority, string> pQueue)
        {
            string dequeued;

            await pQueue.EnqueuedItemsAsync();            //awaiting first not required, TryDequeue can come first as well

            //awaiting EnqueuedItemsAsync must match priority with TryDequeue, here default descending order, otherwise CPU cycles can be burned needlesly
            while (!pQueue.TryDequeu(out dequeued))
            {
                await pQueue.EnqueuedItemsAsync();
            }
            Assert.AreEqual("1Higher", dequeued);

            await pQueue.EnqueuedItemsAsync();            //awaiting first not required, TryDequeue can come first as well

            //awaiting EnqueuedItemsAsync must match priority with TryDequeue, here default descending order, otherwise CPU cycles can be burned needlesly
            while (!pQueue.TryDequeu(out dequeued))
            {
                await pQueue.EnqueuedItemsAsync();
            }
            Assert.AreEqual("2Higher", dequeued);

            await pQueue.EnqueuedItemsAsync();            //awaiting first not required, TryDequeue can come first as well

            //awaiting EnqueuedItemsAsync must match priority with TryDequeue, here default descending order, otherwise CPU cycles can be burned needlesly
            while (!pQueue.TryDequeu(out dequeued))
            {
                await pQueue.EnqueuedItemsAsync();
            }
            Assert.AreEqual("3Higher", dequeued);


            await pQueue.EnqueuedItemsAsync();            //awaiting first not required, TryDequeue can come first as well

            //awaiting EnqueuedItemsAsync must match priority with TryDequeue, here default descending order, otherwise CPU cycles can be burned needlesly
            while (!pQueue.TryDequeu(out dequeued))
            {
                await pQueue.EnqueuedItemsAsync();
            }
            Assert.AreEqual("1Normal", dequeued);

            await pQueue.EnqueuedItemsAsync();            //awaiting first not required, TryDequeue can come first as well

            //awaiting EnqueuedItemsAsync must match priority with TryDequeue, here default descending order, otherwise CPU cycles can be burned needlesly
            while (!pQueue.TryDequeu(out dequeued))
            {
                await pQueue.EnqueuedItemsAsync();
            }
            Assert.AreEqual("2Normal", dequeued);

            await pQueue.EnqueuedItemsAsync();            //awaiting first not required, TryDequeue can come first as well

            //awaiting EnqueuedItemsAsync must match priority with TryDequeue, here default descending order, otherwise CPU cycles can be burned needlesly
            while (!pQueue.TryDequeu(out dequeued))
            {
                await pQueue.EnqueuedItemsAsync();
            }
            Assert.AreEqual("3Normal", dequeued);


            await pQueue.EnqueuedItemsAsync();            //awaiting first not required, TryDequeue can come first as well

            //awaiting EnqueuedItemsAsync must match priority with TryDequeue, here default descending order, otherwise CPU cycles can be burned needlesly
            while (!pQueue.TryDequeu(out dequeued))
            {
                await pQueue.EnqueuedItemsAsync();
            }
            Assert.AreEqual("1Lower", dequeued);

            await pQueue.EnqueuedItemsAsync();            //awaiting first not required, TryDequeue can come first as well

            //awaiting EnqueuedItemsAsync must match priority with TryDequeue, here default descending order, otherwise CPU cycles can be burned needlesly
            while (!pQueue.TryDequeu(out dequeued))
            {
                await pQueue.EnqueuedItemsAsync();
            }
            Assert.AreEqual("2Lower", dequeued);

            await pQueue.EnqueuedItemsAsync();            //awaiting first not required, TryDequeue can come first as well

            //awaiting EnqueuedItemsAsync must match priority with TryDequeue, here default descending order, otherwise CPU cycles can be burned needlesly
            while (!pQueue.TryDequeu(out dequeued))
            {
                await pQueue.EnqueuedItemsAsync();
            }
            Assert.AreEqual("3Lower", dequeued);

            await Task.CompletedTask;
        }