public async Task StreamFlushAsyncThrowingDoesReturnMemoryToPool()
        {
            using (var pool = new DisposeTrackingBufferPool())
            {
                var        stream  = new CancelledWritesStream();
                var        options = new StreamPipeWriterOptions(pool);
                PipeWriter writer  = PipeWriter.Create(stream, options);
                writer.WriteEmpty(10);

                Assert.Equal(1, pool.CurrentlyRentedBlocks);
                Assert.Equal(0, pool.DisposedBlocks);

                ValueTask <FlushResult> task = writer.FlushAsync();
                stream.WaitForWriteTask.TrySetResult(null);
                stream.WaitForFlushTask.TrySetException(new Exception());

                await Assert.ThrowsAsync <Exception>(async() => await task);

                Assert.Equal(0, pool.CurrentlyRentedBlocks);
                Assert.Equal(1, pool.DisposedBlocks);

                writer.Complete();
                Assert.Equal(0, pool.CurrentlyRentedBlocks);
                Assert.Equal(1, pool.DisposedBlocks);
            }
        }
        public async Task CancelingStreamViaCancellationTokenThrowsOperationCancelledException()
        {
            var  stream = new CancelledWritesStream();
            var  cts    = new CancellationTokenSource();
            Task task   = PipeReader.CopyToAsync(stream, cts.Token);

            // Call write async inline, this will yield when it hits the tcs
            Pipe.Writer.WriteEmpty(10);
            await Pipe.Writer.FlushAsync();

            // Then cancel
            cts.Cancel();

            // Now resume the write which should result in an exception
            stream.WaitForWriteTask.TrySetResult(null);

            await Assert.ThrowsAsync <OperationCanceledException>(() => task);
        }
        public async Task CanCancelFlushAsyncWithCancelPendingFlushStreamWriteAsyncThrows()
        {
            var stream = new CancelledWritesStream();

            stream.WaitForFlushTask.TrySetResult(null);

            PipeWriter writer = PipeWriter.Create(stream);

            writer.WriteEmpty(10);
            ValueTask <FlushResult> task = writer.FlushAsync();

            Assert.False(task.IsCompleted);

            writer.CancelPendingFlush();

            stream.WaitForWriteTask.TrySetResult(null);

            FlushResult result = await task;

            Assert.True(result.IsCanceled);
            writer.Complete();
        }
        public async Task CanCancelFlushAsyncWithCancellationTokenWhenStreamWriteAsyncThrows()
        {
            var stream = new CancelledWritesStream();

            stream.WaitForFlushTask.TrySetResult(null);

            var        cts    = new CancellationTokenSource();
            PipeWriter writer = PipeWriter.Create(stream);

            writer.WriteEmpty(10);
            ValueTask <FlushResult> task = writer.FlushAsync(cts.Token);

            Assert.False(task.IsCompleted);

            cts.Cancel();

            stream.WaitForWriteTask.TrySetResult(null);

            await Assert.ThrowsAsync <OperationCanceledException>(async() => await task);

            writer.Complete();
        }