diff --git a/src/libraries/System.IO.FileSystem/tests/FileStream/WriteAsync.cs b/src/libraries/System.IO.FileSystem/tests/FileStream/WriteAsync.cs index 06a9422589ee84..a3077a5e7eb612 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileStream/WriteAsync.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileStream/WriteAsync.cs @@ -100,15 +100,27 @@ public async Task SimpleWriteAsync() } } + [Fact] + public async Task TriggerTheProblemAsync() + { + if (OperatingSystem.IsWindows()) + { + for (int i = 0; i < 10_000; i++) + { + await WriteAsyncCancelledFile(0, FileOptions.Asynchronous | FileOptions.DeleteOnClose); + } + } + } + [Theory] - [InlineData(0, true)] // 0 == no buffering - [InlineData(4096, true)] // 4096 == default buffer size - [InlineData(0, false)] - [InlineData(4096, false)] - public async Task WriteAsyncCancelledFile(int bufferSize, bool isAsync) + [InlineData(0, FileOptions.Asynchronous)] // 0 == no buffering + [InlineData(4096, FileOptions.Asynchronous)] // 4096 == default buffer size + [InlineData(0, FileOptions.None)] + [InlineData(4096, FileOptions.None)] + public async Task WriteAsyncCancelledFile(int bufferSize, FileOptions fileOptions) { const int writeSize = 1024 * 1024; - using (FileStream fs = new FileStream(GetTestFilePath(), FileMode.CreateNew, FileAccess.Write, FileShare.None, bufferSize, isAsync)) + using (FileStream fs = new FileStream(GetTestFilePath(), FileMode.CreateNew, FileAccess.Write, FileShare.None, bufferSize, fileOptions)) { byte[] buffer = new byte[writeSize]; CancellationTokenSource cts = new CancellationTokenSource(); diff --git a/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.OverlappedValueTaskSource.Windows.cs b/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.OverlappedValueTaskSource.Windows.cs index 1ba3516c42a9f1..b0242c679434b6 100644 --- a/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.OverlappedValueTaskSource.Windows.cs +++ b/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.OverlappedValueTaskSource.Windows.cs @@ -200,6 +200,12 @@ internal void Complete(uint errorCode, uint numBytes) OSFileStreamStrategy? strategy = _strategy; ReleaseResources(); + if (errorCode != Interop.Errors.ERROR_SUCCESS && numBytes != 0) + { + _source.SetException(new Exception($"The error code was {errorCode} and numBytes was {numBytes}")); + return; + } + if (strategy is not null && _bufferSize != numBytes) // true only for incomplete operations { strategy.OnIncompleteOperation(_bufferSize, (int)numBytes);