Mises à jour de FileStream.Position après la finalisation de ReadAsync ou de WriteAsync

FileStream.Position est maintenant mis à jour une fois que ReadAsync ou WriteAsync a terminé.

Description de la modification

Dans les versions précédentes de .NET sur Windows, FileStream.Position est mis à jour après le démarrage de l’opération de lecture ou d’écriture asynchrone. À partir de .NET 6, FileStream.Position est mis à jour une fois ces opérations terminées.

Le code suivant montre comment la valeur de FileStream.Position diffère entre les versions .NET précédentes et .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 introduite

.NET 6

Raison du changement

FileStream n’a jamais été thread-safe, mais jusqu’à .NET 6, .NET essayait de prendre en charge plusieurs appels simultanés à ses méthodes asynchrones (ReadAsync et WriteAsync) sur Windows.

Cette modification a été introduite pour autoriser les E/S de fichier 100 % asynchrones avec FileStream et pour résoudre les problèmes suivants :

À présent, lorsque la mise en mémoire tampon est activée (autrement dit, quand l’argument bufferSize passé au constructeur FileStream est supérieur à 1), chaque opération ReadAsync et WriteAsync est sérialisée.

  • Modifiez tout code qui s’appuyait sur la position définie avant la fin des opérations.

  • Pour activer le comportement .NET 5 dans .NET 6, spécifiez un commutateur AppContext ou une variable d’environnement. En définissant le commutateur sur true, 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