FileStream.Position viene aggiornato dopo il completamento di ReadAsync o WriteAsync

FileStream.Position viene ora aggiornato dopo il completamento di ReadAsync o WriteAsync.

Descrizione delle modifiche

Nelle versioni precedenti di .NET in Windows, FileStream.Position viene aggiornato dopo l'avvio dell'operazione di lettura o scrittura asincrona. A partire da .NET 6, FileStream.Position viene aggiornato al termine di tali operazioni.

Il codice seguente illustra le differenze del valore di FileStream.Position tra le versioni precedenti di .NET e .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
}

Versione di introduzione

.NET 6

Motivo della modifica

FileStream non è mai stato thread-safe, ma fino a .NET 6, .NET ha provato a supportare più chiamate simultanee ai relativi metodi asincroni (ReadAsync e WriteAsync) in Windows.

Questa modifica è stata introdotta per consentire l'I/O di file asincrono al 100% con FileStream e per risolvere i problemi seguenti:

Quando il buffering è abilitato, ovvero l'argomento bufferSize passato al costruttore FileStream è maggiore di 1, ogni operazione ReadAsync e WriteAsync viene serializzata.

  • Modificare tutto il codice che si basava sull'impostazione della posizione prima del completamento delle operazioni.

  • Per abilitare il comportamento di .NET 5 in .NET 6, specificare un'opzione AppContext o una variabile di ambiente. Impostando l'opzione su true, si rifiutano esplicitamente tutti i miglioramenti delle prestazioni apportati a FileStream in .NET 6.

    {
        "configProperties": {
            "System.IO.UseNet5CompatFileStream": true
        }
    }
    
    set DOTNET_SYSTEM_IO_USENET5COMPATFILESTREAM=1
    

    Nota

    Questa opzione è disponibile solo in .NET 6. È stata rimossa in .NET 7.

API interessate