@@ -130,16 +130,10 @@ public virtual Task CopyToAsync(PipeWriter destination, CancellationToken cancel
130130return Task . FromCanceled ( cancellationToken ) ;
131131}
132132
133- return CopyToAsyncCore ( destination , async ( destination , memory , cancellationToken ) =>
134- {
135- FlushResult result = await destination . WriteAsync ( memory , cancellationToken ) . ConfigureAwait ( false ) ;
136-
137- if ( result . IsCanceled )
138- {
139- ThrowHelper . ThrowOperationCanceledException_FlushCanceled ( ) ;
140- }
141- } ,
142- cancellationToken ) ;
133+ return CopyToAsyncCore (
134+ destination ,
135+ ( destination , memory , cancellationToken ) => destination . WriteAsync ( memory , cancellationToken ) ,
136+ cancellationToken ) ;
143137}
144138
145139/// <summary>Asynchronously reads the bytes from the <see cref="System.IO.Pipelines.PipeReader" /> and writes them to the specified stream, using a specified cancellation token.</summary>
@@ -158,13 +152,28 @@ public virtual Task CopyToAsync(Stream destination, CancellationToken cancellati
158152return Task . FromCanceled ( cancellationToken ) ;
159153}
160154
161- return CopyToAsyncCore (
162- destination ,
163- ( destination , memory , cancellationToken ) => destination . WriteAsync ( memory , cancellationToken ) ,
164- cancellationToken ) ;
155+ return CopyToAsyncCore ( destination , ( destination , memory , cancellationToken ) =>
156+ {
157+ ValueTask task = destination . WriteAsync ( memory , cancellationToken ) ;
158+
159+ if ( task . IsCompletedSuccessfully )
160+ {
161+ task . GetAwaiter ( ) . GetResult ( ) ;
162+ return new ValueTask < FlushResult > ( new FlushResult ( isCanceled : false , isCompleted : false ) ) ;
163+ }
164+
165+ static async ValueTask < FlushResult > Awaited ( ValueTask writeTask )
166+ {
167+ await writeTask . ConfigureAwait ( false ) ;
168+ return new FlushResult ( isCanceled : false , isCompleted : false ) ;
169+ }
170+
171+ return Awaited ( task ) ;
172+ } ,
173+ cancellationToken ) ;
165174}
166175
167- private async Task CopyToAsyncCore < TStream > ( TStream destination , Func < TStream , ReadOnlyMemory < byte > , CancellationToken , ValueTask > writeAsync , CancellationToken cancellationToken )
176+ private async Task CopyToAsyncCore < TStream > ( TStream destination , Func < TStream , ReadOnlyMemory < byte > , CancellationToken , ValueTask < FlushResult > > writeAsync , CancellationToken cancellationToken )
168177{
169178while ( true )
170179{
@@ -182,9 +191,19 @@ private async Task CopyToAsyncCore<TStream>(TStream destination, Func<TStream, R
182191
183192while ( buffer . TryGet ( ref position , out ReadOnlyMemory < byte > memory ) )
184193{
185- await writeAsync ( destination , memory , cancellationToken ) . ConfigureAwait ( false ) ;
194+ FlushResult flushResult = await writeAsync ( destination , memory , cancellationToken ) . ConfigureAwait ( false ) ;
195+
196+ if ( flushResult . IsCanceled )
197+ {
198+ ThrowHelper . ThrowOperationCanceledException_FlushCanceled ( ) ;
199+ }
186200
187201consumed = position ;
202+
203+ if ( flushResult . IsCompleted )
204+ {
205+ return ;
206+ }
188207}
189208
190209// The while loop completed succesfully, so we've consumed the entire buffer.