public async Task AsyncSendAndCloseAndReceiveAll(int count)
        {
            var cancellation = new CancellationTokenSource(TimeSpan.FromSeconds(5));
            var asyncQueue   = new AsyncQueue <int>();

            var sendValue = 0;
            var sendTask  = new Func <Task>(async() =>
            {
                await Task.Yield();
                while (cancellation.IsCancellationRequested == false)
                {
                    if (asyncQueue.TryEnqueue(sendValue++) == false)
                    {
                        return;
                    }
                    await Task.Delay(10).ConfigureAwait(false);
                }
            })().IgnoreFaultOrCancellation().ConfigureAwait(false);

            await Task.Delay(count);

            var actualSum = asyncQueue.TakeAllAndClose().Sum();

            await sendTask;

            var expectedSum = Enumerable.Range(0, sendValue).Sum();

            Assert.NotEqual(expectedSum, actualSum);
            Assert.Equal(0, asyncQueue.Count);
            cancellation.Cancel();
        }
        public async Task DequeueAsyncCloseReceiveAllCancellation()
        {
            var asyncQueue   = new AsyncQueue <int>();
            var cancellation = new CancellationTokenSource(2000);
            var receiveAsync = asyncQueue.DequeueAsync(cancellation.Token);

            var timeout  = Task.Delay(1000);
            var recvTask = Assert.ThrowsAsync <OperationCanceledException>(async() =>
            {
                await receiveAsync.ConfigureAwait(false);
            });

            var all = asyncQueue.TakeAllAndClose(closeError: new OperationCanceledException());

            if (await Task.WhenAny(timeout, recvTask).ConfigureAwait(false) == timeout)
            {
                throw new TimeoutException();
            }

            Assert.Empty(all);
            Assert.Equal(0, asyncQueue.Count);
        }
        public async Task ParallelSendAndCloseReceiveAll(int count)
        {
            var cancellationSource = new CancellationTokenSource();
            var asyncQueue         = new AsyncQueue <int>();
            var options            = new ParallelOptions {
                CancellationToken = cancellationSource.Token, MaxDegreeOfParallelism = Environment.ProcessorCount / 2, TaskScheduler = TaskScheduler.Default
            };
            var items = new ConcurrentQueue <int>(Enumerable.Range(0, count));

            var sendTask = Task.Factory.StartNew(() => Parallel.For(0, count, options, i =>
            {
                var item = default(int);
                if (items.TryDequeue(out item))
                {
                    if (asyncQueue.TryEnqueue(item) == false)
                    {
                        items.Enqueue(item);
                    }
                }
            }));

            await Task.Delay(1).ConfigureAwait(false);

            var itemsInAsyncQueue = asyncQueue.TakeAllAndClose(); // deny TryEnqueue

            cancellationSource.Cancel();                          // stop parallel for

            await sendTask.IgnoreFaultOrCancellation().ConfigureAwait(false);

            var actualCount = items.Count + itemsInAsyncQueue.Count;

            this.logger.Debug($"[TEST] en-queued: {itemsInAsyncQueue.Count}, total: {count}");

            Assert.Equal(count, actualCount);
            Assert.Equal(0, asyncQueue.Count);
        }