public void CompleteAbortsPendingReadTasks()
        {
            var sut       = new BufferedChannel <int>(0);
            var readTask1 = sut.ReadAsync();
            var readTask2 = sut.ReadAsync();

            sut.Complete();
            Should.Throw <TaskCanceledException>(() => readTask1.AsTask(), Timeout1Sec);
            Should.Throw <TaskCanceledException>(() => readTask2.AsTask(), Timeout1Sec);
        }
#pragma warning disable xUnit1026 // Theory methods should use all of their parameters
        public void CanWriteAndReadFromSeveralThreadsConcurrently(int writeThreads, int readThreads, int bufferSize)
#pragma warning restore xUnit1026 // Theory methods should use all of their parameters
        {
            var writeCount = readThreads * 100;
            var readCount  = writeThreads * 100;
            var sut        = new BufferedChannel <int>(bufferSize);

            async Task WriteWorker()
            {
                for (var i = 0; i < writeCount; i++)
                {
                    await sut.WriteAsync(i).ConfigureAwait(false);
                }
            }

            async Task ReadWorker()
            {
                for (var i = 0; i < readCount; i++)
                {
                    await sut.ReadAsync().ConfigureAwait(false);
                }
            }

            var writeTasks = Enumerable.Range(0, writeThreads).Select(_ => Task.Run(WriteWorker));
            var readTasks  = Enumerable.Range(0, readThreads).Select(_ => Task.Run(ReadWorker));
            var allTasks   = writeTasks.Concat(readTasks).ToArray();

            Task.WhenAll(allTasks).ShouldCompleteIn(Timeout10Sec);

            sut.TryRead(out int _).ShouldBe(false);
            sut.TryComplete().ShouldBe(true);
        }
        public void WritesSynchronouslyWhenThereIsPendingReadTask()
        {
            var sut      = new BufferedChannel <int>(0);
            var readTask = sut.ReadAsync();

            sut.TryWriteSafe(1).ShouldBe(false);
            sut.WriteAsync(1).ShouldCompleteIn(Timeout1Sec);
            Should.CompleteIn(readTask.AsTask(), TimeSpan.FromSeconds(1));
            readTask.Result.ShouldBe(1);
        }
        public void CanReadAfterCompletionUntilBufferIsEmpty()
        {
            var sut = new BufferedChannel <int>(2);

            sut.TryWrite(1);
            sut.TryWrite(2);
            sut.TryComplete();
            sut.Completion.IsCompleted.ShouldBe(false);
            sut.TryRead(out int _).ShouldBe(true);
            sut.Completion.IsCompleted.ShouldBe(false);
            sut.TryRead(out int _).ShouldBe(true);
            sut.Completion.IsCompleted.ShouldBe(true);
            sut.TryRead(out int _).ShouldBe(false);
            Should.Throw <TaskCanceledException>(() => sut.ReadAsync().AsTask());
        }