diff --git a/src/System.IO.FileSystem/src/System/IO/Win32FileStream.cs b/src/System.IO.FileSystem/src/System/IO/Win32FileStream.cs index 83ad2640cf39..2fb4dca02255 100644 --- a/src/System.IO.FileSystem/src/System/IO/Win32FileStream.cs +++ b/src/System.IO.FileSystem/src/System/IO/Win32FileStream.cs @@ -1764,22 +1764,25 @@ private async Task AsyncModeCopyToAsync(Stream destination, int bufferSize, Canc // whatever read operation may currently be in progress, if there is one. It's possible the cancellation // request could come in between operations, in which case we flag that with explicit calls to ThrowIfCancellationRequested // in the read/write copy loop. - cancellationReg = cancellationToken.Register(s => + if (cancellationToken.CanBeCanceled) { - var innerAwaitable = (AsyncCopyToAwaitable)s; - unsafe + cancellationReg = cancellationToken.Register(s => { - lock (innerAwaitable.CancellationLock) // synchronize with cleanup of the overlapped + var innerAwaitable = (AsyncCopyToAwaitable)s; + unsafe { - if (innerAwaitable._nativeOverlapped != null) - { - // Try to cancel the I/O. We ignore the return value, as cancellation is opportunistic and we - // don't want to fail the operation because we couldn't cancel it. - Interop.mincore.CancelIoEx(innerAwaitable._fileStream._handle, innerAwaitable._nativeOverlapped); + lock (innerAwaitable.CancellationLock) // synchronize with cleanup of the overlapped + { + if (innerAwaitable._nativeOverlapped != null) + { + // Try to cancel the I/O. We ignore the return value, as cancellation is opportunistic and we + // don't want to fail the operation because we couldn't cancel it. + Interop.mincore.CancelIoEx(innerAwaitable._fileStream._handle, innerAwaitable._nativeOverlapped); + } } } - } - }, readAwaitable); + }, readAwaitable); + } // Repeatedly read from this FileStream and write the results to the destination stream. while (true)