public void Write_TimeoutUntilRead()
        {
            var buffer = new byte[] { 1, 2, 3 };
            using (var stream = new BlockingMemoryStream(boundedCapacity: 2))
            {
                // Write one byte more than the capacity, should cause the write to block.
                var writeTask = new TaskFactory().StartNew(() =>
                    stream.Write(buffer, 0, 3)
                );
                Assert.IsFalse(writeTask.Wait(millisecondsTimeout: 100));

                // Read one byte
                var readByteTask = new TaskFactory().StartNew(() =>
                    stream.ReadByte()
                );
                Assert.IsTrue(readByteTask.Wait(millisecondsTimeout: 1000));
                Assert.AreEqual(1, readByteTask.Result);

                // Now there should be enough buffer space to finish the write task.
                Assert.IsTrue(writeTask.Wait(millisecondsTimeout: 1000));
            }
        }
        public void WriteThenReadToEnd_StopsBlockingWhenCompleteWriting()
        {
            var buffer = new byte[] { 1, 2, 3 };
            using (var stream = new BlockingMemoryStream())
            {
                stream.Write(buffer, 0, buffer.Length);

                // We can read a byte without hitting any blocking
                var readByteTask = new TaskFactory().StartNew(() => stream.ReadByte());
                Assert.IsTrue(readByteTask.Wait(millisecondsTimeout: 1000));
                Assert.AreEqual(1, readByteTask.Result);

                // If we try to read to the end, then we should block until we call CompleteWriting
                var readToEndTask = new TaskFactory().StartNew(() => StreamUtils.ReadToEnd(stream));
                Assert.IsFalse(readToEndTask.Wait(millisecondsTimeout: 100));

                stream.CompleteWriting();

                Assert.IsTrue(readToEndTask.Wait(millisecondsTimeout: 1000));
                CollectionAssert.AreEqual(buffer.Skip(1), readToEndTask.Result);
            }
        }