FileStream už nesynchronizuje posun souboru s operačním systémem
Pokud chcete zvýšit výkon, FileStream už nesynchronizuje posun souboru s operačním systémem.
Změna popisu
V předchozích verzích FileStream .NET synchronizuje posun souboru s operačním systémem Windows při čtení nebo zápisu do souboru. Synchronizuje posun voláním SetFilePointer, což je nákladné systémové volání. Počínaje rozhraním .NET 6 FileStream se už nesynchronizuje posun souboru a místo toho zůstane posun v paměti. FileStream.Position vždy vrátí aktuální posun, ale pokud získáte popisovač souboru z FileStream.SafeFileHandle operačního systému a dotazujete se na operační systém pro posun aktuálního souboru pomocí systémového volání, hodnota posunu bude 0.
Následující kód ukazuje, jak se posun souboru liší mezi předchozími verzemi .NET a .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
}
}
Zavedená verze
.NET 6
Důvod změny
Tato změna byla zavedena za účelem zlepšení výkonu asynchronních čtení a zápisů a řešení následujících problémů:
- Win32 FileStream vydá hledání při každém volání ReadAsync
- FileStream.Windows useAsync WriteAsync volání blokující rozhraní API
Díky této změně ReadAsync jsou operace až dvakrát rychlejší a WriteAsync operace jsou až pětkrát rychlejší.
Doporučená akce
Upravte veškerý kód, který spoléhal na synchronizaci posunu.
Pokud chcete povolit chování .NET 5 v .NET 6, zadejte
AppContext
přepínač nebo proměnnou prostředí. Nastavením přepínače natrue
možnost se odhlásíte ze všech vylepšení výkonu provedenýchFileStream
v .NET 6.{ "configProperties": { "System.IO.UseNet5CompatFileStream": true } }
set DOTNET_SYSTEM_IO_USENET5COMPATFILESTREAM=1
Poznámka:
Tento přepínač je k dispozici pouze v .NET 6. Byl odebrán v .NET 7.
Ovlivněná rozhraní API
Nezaokrouhlovat.