FileStream.Position updates after ReadAsync or WriteAsync completes
FileStream.Position is now updated after ReadAsync or WriteAsync completes.
Change description
In previous .NET versions on Windows, FileStream.Position is updated after the asynchronous read or write operation starts. Starting in .NET 6, FileStream.Position is updated after those operations complete.
The following code shows how the value of FileStream.Position differs between previous .NET versions and .NET 6.
byte[] bytes = new byte[10_000];
string path = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize: 4096, useAsync: true))
{
Task[] writes = new Task[3];
writes[0] = fs.WriteAsync(bytes, 0, bytes.Length);
Console.WriteLine(fs.Position); // 10000 in .NET 5, 0 in .NET 6
writes[1] = fs.WriteAsync(bytes, 0, bytes.Length);
Console.WriteLine(fs.Position); // 20000 in .NET 5, 0 in .NET 6
writes[2] = fs.WriteAsync(bytes, 0, bytes.Length);
Console.WriteLine(fs.Position); // 30000 in .NET 5, 0 in .NET 6
await Task.WhenAll(writes);
Console.WriteLine(fs.Position); // 30000 in all versions
}
Version introduced
.NET 6
Reason for change
FileStream has never been thread-safe, but until .NET 6, .NET has tried to support multiple concurrent calls to its asynchronous methods (ReadAsync and WriteAsync) on Windows.
This change was introduced to allow for 100% asynchronous file I/O with FileStream and to fix the following issues:
- FileStream.FlushAsync ends up doing synchronous writes
- Win32 FileStream turns async reads into sync reads
Now, when buffering is enabled (that is, the bufferSize
argument that's passed to the FileStream constructor is greater than 1), every ReadAsync and WriteAsync operation is serialized.
Recommended action
Modify any code that relied on the position being set before operations completed.
To enable the .NET 5 behavior in .NET 6, specify an
AppContext
switch or an environment variable. By setting the switch totrue
, you opt out of all performance improvements made toFileStream
in .NET 6.{ "configProperties": { "System.IO.UseNet5CompatFileStream": true } }
set DOTNET_SYSTEM_IO_USENET5COMPATFILESTREAM=1
Note
This switch is only available in .NET 6. It was removed in .NET 7.
Affected APIs
Feedback
https://aka.ms/ContentUserFeedback.
Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see:Submit and view feedback for