FileStream ne synchronise plus le décalage de fichier avec le système d’exploitation
Pour améliorer le niveau de performance, FileStream ne synchronise plus le décalage de fichier avec le système d’exploitation.
Description de la modification
Dans les versions précédentes de .NET, FileStream synchronise le décalage de fichier avec le système d’exploitation Windows lorsqu’il lit ou écrit dans un fichier. Il synchronise le décalage en appelant SetFilePointer, qui est un appel système coûteux. À partir de .NET 6, FileStream ne synchronise plus le décalage de fichier et conserve simplement le décalage en mémoire. FileStream.Position retourne toujours le décalage actuel, mais si vous obtenez le descripteur de fichier à partir de FileStream.SafeFileHandle et interrogez le système d’exploitation pour le décalage de fichier actuel à l’aide d’un appel système, la valeur de décalage sera 0.
Le code suivant montre comment le décalage de fichier diffère entre les versions .NET précédentes et .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
}
}
Version introduite
.NET 6
Raison du changement
Ce changement a été introduit pour améliorer le niveau de performance des lectures et écritures asynchrones et pour résoudre les problèmes suivants :
- Le flux de fichier Win32 émet une recherche sur chaque appel ReadAsync
- FileStream.Windows useAsync WriteAsync appelle des API bloquantes
Avec ce changement, les opérations ReadAsync sont jusqu’à deux fois plus rapides et les opérations WriteAsync sont jusqu’à cinq fois plus rapides.
Action recommandée
Modifiez tout code qui s’appuyait sur le décalage en cours de synchronisation.
Pour activer le comportement .NET 5 dans .NET 6, spécifiez un commutateur
AppContext
ou une variable d’environnement. En définissant le commutateur surtrue
, vous désactivez toutes les améliorations du niveau de performance apportées àFileStream
dans .NET 6.{ "configProperties": { "System.IO.UseNet5CompatFileStream": true } }
set DOTNET_SYSTEM_IO_USENET5COMPATFILESTREAM=1
Notes
Ce commutateur est disponible uniquement dans .NET 6. Il a été supprimé dans .NET 7.
API affectées
Aucun.