Added ConfigureAwait(false) to the Stream.ReadAsync call (dotnet/corefx#36621)
authorDavid Fowler <davidfowl@gmail.com>
Fri, 5 Apr 2019 17:46:09 +0000 (10:46 -0700)
committerGitHub <noreply@github.com>
Fri, 5 Apr 2019 17:46:09 +0000 (10:46 -0700)
* Added ConfigureAwait(false) to the Stream.ReadAsync call
* Make tests less flaky

Commit migrated from https://github.com/dotnet/corefx/commit/f7adff5131e97cfcdfb76014e34101fd75c5340b

src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/StreamPipeReader.cs
src/libraries/System.IO.Pipelines/tests/PipeReaderCopyToAsyncTests.cs
src/libraries/System.IO.Pipelines/tests/StreamPipeReaderTests.cs

index 059535016b3156943c1862b159352fa3a356bc45..9f1e292c5d062675558592955293dded0f85309e 100644 (file)
@@ -211,7 +211,7 @@ namespace System.IO.Pipelines
             var reg = new CancellationTokenRegistration();
             if (cancellationToken.CanBeCanceled)
             {
-                reg = cancellationToken.Register(state => ((StreamPipeReader)state).Cancel(), this);
+                reg = cancellationToken.UnsafeRegister(state => ((StreamPipeReader)state).Cancel(), this);
             }
 
             using (reg)
@@ -223,7 +223,7 @@ namespace System.IO.Pipelines
 
                     Memory<byte> buffer = _readTail.AvailableMemory.Slice(_readTail.End);
 
-                    int length = await InnerStream.ReadAsync(buffer, tokenSource.Token);
+                    int length = await InnerStream.ReadAsync(buffer, tokenSource.Token).ConfigureAwait(false);
 
                     Debug.Assert(length + _readTail.End <= _readTail.AvailableMemory.Length);
 
index 3b4f337526f90e1706c8138d10937e1c67308bbd..07b7a60ea5dca692cf94e7254cad7d62fc3e48f4 100644 (file)
@@ -13,7 +13,7 @@ namespace System.IO.Pipelines.Tests
 {
     public class CopyToAsyncTests
     {
-        private static readonly PipeOptions s_testOptions = new PipeOptions(readerScheduler: PipeScheduler.Inline);
+        private static readonly PipeOptions s_testOptions = new PipeOptions(readerScheduler: PipeScheduler.Inline, useSynchronizationContext: false);
 
         [Fact]
         public async Task CopyToAsyncThrowsArgumentNullExceptionForNullDestination()
@@ -71,7 +71,7 @@ namespace System.IO.Pipelines.Tests
         {
             using (var pool = new TestMemoryPool())
             {
-                var pipe = new Pipe(new PipeOptions(pool: pool, readerScheduler: PipeScheduler.Inline));
+                var pipe = new Pipe(s_testOptions);
                 pipe.Writer.WriteEmpty(4096);
                 pipe.Writer.WriteEmpty(4096);
                 pipe.Writer.WriteEmpty(4096);
index f8efbc60f0c1f0f6ed239068148b0bf963e6b1c7..1bc60321eba29975ed5aa73f4b8ea8c10e753ebc 100644 (file)
@@ -67,12 +67,15 @@ namespace System.IO.Pipelines.Tests
         [Fact]
         public async Task CanReadMultipleTimes()
         {
-            static async Task DoAsyncRead(PipeReader reader, int[] bufferSizes)
+            // This needs to run inline to synchronize the reader and writer
+            TaskCompletionSource<object> waitForRead = null;
+
+            async Task DoAsyncRead(PipeReader reader, int[] bufferSizes)
             {
                 var index = 0;
                 while (true)
                 {
-                    ReadResult readResult = await reader.ReadAsync();
+                    ReadResult readResult = await reader.ReadAsync().ConfigureAwait(false);
 
                     if (readResult.IsCompleted)
                     {
@@ -82,24 +85,27 @@ namespace System.IO.Pipelines.Tests
                     Assert.Equal(bufferSizes[index], readResult.Buffer.Length);
                     reader.AdvanceTo(readResult.Buffer.End);
                     index++;
+                    waitForRead?.TrySetResult(null);
                 }
 
                 reader.Complete();
             }
 
-            static async Task DoAsyncWrites(PipeWriter writer, int[] bufferSizes)
+            async Task DoAsyncWrites(PipeWriter writer, int[] bufferSizes)
             {
                 for (int i = 0; i < bufferSizes.Length; i++)
                 {
                     writer.WriteEmpty(bufferSizes[i]);
-                    await writer.FlushAsync();
+                    waitForRead = new TaskCompletionSource<object>();
+                    await writer.FlushAsync().ConfigureAwait(false);
+                    await waitForRead.Task;
                 }
 
                 writer.Complete();
             }
 
             // We're using the pipe here as a way to pump bytes into the reader asynchronously
-            var pipe = new Pipe(new PipeOptions(readerScheduler: PipeScheduler.Inline));
+            var pipe = new Pipe();
             var options = new StreamPipeReaderOptions(bufferSize: 4096);
             PipeReader reader = PipeReader.Create(pipe.Reader.AsStream(), options);
 
@@ -110,6 +116,8 @@ namespace System.IO.Pipelines.Tests
 
             await readingTask;
             await writingTask;
+
+            pipe.Reader.Complete();
         }
 
         [Theory]
@@ -469,6 +477,8 @@ namespace System.IO.Pipelines.Tests
             reader.AdvanceTo(readResult.Buffer.End);
 
             reader.Complete();
+
+            pipe.Writer.Complete();
         }
 
         [Fact]