FileStream ya no sincroniza el desplazamiento de archivo con el sistema operativo
Para mejorar el rendimiento, FileStream ya no sincroniza el desplazamiento de archivo con el sistema operativo.
Descripción del cambio
En versiones anteriores de .NET, FileStream sincroniza el desplazamiento de archivo con el sistema operativo (SO) Windows cuando lee o escribe en un archivo. Sincroniza el desplazamiento mediante una llamada a SetFilePointer, que es una llamada del sistema costosa. A partir de .NET 6, FileStream ya no sincroniza el desplazamiento de archivo, sino que simplemente mantiene el desplazamiento en memoria. FileStream.Position siempre devuelve el desplazamiento actual, pero si obtiene el identificador de archivo de FileStream.SafeFileHandle y consulta al sistema operativo para obtener el desplazamiento de archivo actual mediante una llamada del sistema, el valor de desplazamiento será 0.
El código siguiente muestra cómo difiere el desplazamiento de archivo entre las versiones anteriores de .NET y .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
}
}
Versión introducida
.NET 6
Motivo del cambio
Este cambio se ha incorporado para mejorar el rendimiento de las lecturas y escrituras asincrónicas y para solucionar los problemas siguientes:
- FileStream de Win32 emite una búsqueda en cada llamada ReadAsync
- Filestream.Windows useAsync WriteAsync llama a API de bloqueo
Con este cambio, las operaciones de ReadAsync son hasta dos veces más rápidas, y las operaciones de WriteAsync hasta cinco veces más rápidas.
Acción recomendada
Modifique cualquier código que dependa de la sincronización del desplazamiento.
Para habilitar el comportamiento de .NET 5 en .NET 6, especifique un modificador
AppContext
o una variable de entorno. Al establecer el modificador entrue
, opta por no recibir todas las mejoras de rendimiento realizadas enFileStream
en .NET 6.{ "configProperties": { "System.IO.UseNet5CompatFileStream": true } }
set DOTNET_SYSTEM_IO_USENET5COMPATFILESTREAM=1
Nota
Este modificador solo está disponible en .NET 6. Se quitó en .NET 7.
API afectadas
Ninguno.
Consulte también
Comentarios
https://aka.ms/ContentUserFeedback.
Próximamente: A lo largo de 2024 iremos eliminando gradualmente GitHub Issues como mecanismo de comentarios sobre el contenido y lo sustituiremos por un nuevo sistema de comentarios. Para más información, vea:Enviar y ver comentarios de