FileStream.Position-Aktualisierung nach Abschluss von ReadAsync oder WriteAsync

FileStream.Position wird nun nach Abschluss von ReadAsync oder WriteAsync aktualisiert.

Beschreibung der Änderung:

In früheren .NET-Versionen unter Windows wurde FileStream.Position nach Beginn der asynchronen Lese- oder Schreibvorgänge aktualisiert. Ab .NET 6 wird FileStream.Position nach Abschluss dieser Vorgänge aktualisiert.

Der folgende Code zeigt, wie sich der Wert von FileStream.Position zwischen früheren .NET-Versionen und .NET 6 unterscheidet.

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
}

Eingeführt in Version

.NET 6

Grund für die Änderung

FileStream war noch nie threadsicher, bis .NET 6 versuchte .NET jedoch, mehrere gleichzeitige Aufrufe für die asynchronen Methoden ReadAsync und WriteAsync unter Windows zu unterstützen.

Diese Änderung wurde eingeführt, um einen zu 100 Prozent asynchronen Datei-E/A mit FileStream zu ermöglichen und die folgenden Probleme zu beheben:

Nun wird bei aktivierter Pufferung (das heißt, das Argument bufferSize, das an den FileStream-Konstruktor übergeben wird, ist größer als 1) jeder ReadAsync- und WriteAsync-Vorgang serialisiert.

  • Ändern Sie Code, für den die Position festgelegt werden musste, bevor Vorgänge abgeschlossen wurden.

  • Zum Aktivieren des .NET 5-Verhaltens in .NET 6 geben Sie einen AppContext-Parameter oder eine Umgebungsvariable an. Indem Sie den Parameter auf true festlegen, können Sie alle Leistungsverbesserungen in .NET 6 deaktivieren, die an FileStream vorgenommen wurden.

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

    Hinweis

    Diese Option ist nur in .NET 6 verfügbar. Sie wurde in .NET 7 entfernt.

Betroffene APIs