Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Чтобы повысить производительность, FileStream больше не синхронизирует смещение файла с операционной системой.
Описание изменения
В предыдущих версиях FileStream .NET синхронизирует смещение файла с операционной системой Windows при чтении или записи в файл. Он синхронизирует смещение путем вызова SetFilePointer, который является дорогостоящим системным вызовом. Начиная с .NET 6, FileStream больше не синхронизирует смещение файла и вместо этого просто сохраняет смещение в памяти. FileStream.Position всегда возвращает текущее смещение, но если вы получаете дескриптор файла из FileStream.SafeFileHandle и запрашиваете ОС о текущем смещении файла с помощью системного вызова, значение смещения будет равно 0.
В следующем коде показано, чем отличается смещение файла в предыдущих версиях .NET по сравнению с .NET 6.
[DllImport("kernel32.dll")]
private static extern bool SetFilePointerEx(SafeFileHandle hFile, long liDistanceToMove, out long lpNewFilePointer, uint dwMoveMethod);
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))
{
SafeFileHandle handle = fs.SafeFileHandle;
await fs.WriteAsync(bytes, 0, bytes.Length);
Console.WriteLine(fs.Position); // 10000 in all versions
if (SetFilePointerEx(handle, 0, out long currentOffset, 1 /* get current offset */))
{
Console.WriteLine(currentOffset); // 10000 in .NET 5, 0 in .NET 6
}
}
Представленная версия
.NET 6
Причина изменения
Это изменение было введено для повышения производительности асинхронных операций чтения и записи и устранения следующих проблем:
- Win32 FileStream выполняет операцию поиска при каждом вызове функции ReadAsync
- FileStream.Windows useAsync WriteAsync вызывает блокирующие API
С этим изменением ReadAsync операции выполняются до двух раз быстрее, а WriteAsync операции — до пяти раз быстрее.
Рекомендуемое действие
Измените любой код, зависящий от синхронизированного смещения.
Чтобы включить поведение .NET 5 в .NET 6, укажите
AppContext
переключатель или переменную среды. Установив переключательtrue
, вы отказываетесь от всех улучшений производительности, осуществленныхFileStream
в .NET 6.{ "configProperties": { "System.IO.UseNet5CompatFileStream": true } }
set DOTNET_SYSTEM_IO_USENET5COMPATFILESTREAM=1
Замечание
Этот переключатель доступен только в .NET 6. Он был удален в .NET 7.
Затронутые API
Нет.