FileStream.Position 在 ReadAsync 或 WriteAsync 完成后更新
现在,FileStream.Position 在 ReadAsync 或 WriteAsync 完成后更新。
更改说明
在 Windows .NET 早期版本中,FileStream.Position 在异步读取或写入操作开始后更新。 从 .NET 6 开始,FileStream.Position 在这些操作完成后更新。
以下代码展示了 FileStream.Position 值在 .NET 早期版本与 .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
}
引入的版本
.NET 6
更改原因
FileStream 从来都不是线程安全的,但在 .NET 6 之前,.NET 已经尝试在 Windows 上支持对其异步方法(ReadAsync 和 WriteAsync)的多个并发调用。
引入此更改是为了允许通过 FileStream 进行 100% 异步文件 I/O,并修复以下问题:
现在,启用缓冲后(即传递到 FileStream 构造函数的 bufferSize
参数大于 1),每个 ReadAsync 和 WriteAsync 操作都将序列化。
建议的操作
修改任何依赖于操作完成前设置的位置的代码。
若要在 .NET 6 中启用 .NET 5 行为,请指定
AppContext
开关或环境变量。 通过将开关设置为true
,可以选择退出 .NET 6 中对FileStream
进行的所有性能改进。{ "configProperties": { "System.IO.UseNet5CompatFileStream": true } }
set DOTNET_SYSTEM_IO_USENET5COMPATFILESTREAM=1
注意
此开关仅在 .NET 6 中可用。 .NET 7 中已经删除了它。
受影响的 API
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈