Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Vytvářejte aplikace univerzální platformy Windows (UPW), které efektivně přistupují k systému souborů, a vyhněte se problémům s výkonem kvůli latenci disku a cyklům paměti/procesoru.
Pokud chcete získat přístup k velké kolekci souborů a chcete získat přístup k hodnotám vlastností kromě typických vlastností Name, FileType a Path, přistupovat k nim vytvořením QueryOptions a voláním SetPropertyPrefetch. Metoda SetPropertyPrefetch může výrazně zlepšit výkon aplikací, které zobrazují kolekci položek získaných ze systému souborů, například kolekci obrázků. Další sada příkladů ukazuje několik způsobů přístupu k více souborům.
První příklad používá Windows.Storage.StorageFolder.GetFilesAsync k načtení informací o názvu sady souborů. Tento přístup poskytuje dobrý výkon, protože příklad přistupuje pouze k vlastnosti name.
StorageFolder library = Windows.Storage.KnownFolders.PicturesLibrary;
IReadOnlyList<StorageFile> files = await library.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByDate);
for (int i = 0; i < files.Count; i++)
{
// do something with the name of each file
string fileName = files[i].Name;
}
Dim library As StorageFolder = Windows.Storage.KnownFolders.PicturesLibrary
Dim files As IReadOnlyList(Of StorageFile) =
Await library.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByDate)
For i As Integer = 0 To files.Count - 1
' do something with the name of each file
Dim fileName As String = files(i).Name
Next i
Druhý příklad používá Windows.Storage.StorageFolder.GetFilesAsync a potom načte vlastnosti obrázku pro každý soubor. Tento přístup poskytuje nízký výkon.
StorageFolder library = Windows.Storage.KnownFolders.PicturesLibrary;
IReadOnlyList<StorageFile> files = await library.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByDate);
for (int i = 0; i < files.Count; i++)
{
ImageProperties imgProps = await files[i].Properties.GetImagePropertiesAsync();
// do something with the date the image was taken
DateTimeOffset date = imgProps.DateTaken;
}
Dim library As StorageFolder = Windows.Storage.KnownFolders.PicturesLibrary
Dim files As IReadOnlyList(Of StorageFile) = Await library.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByDate)
For i As Integer = 0 To files.Count - 1
Dim imgProps As ImageProperties =
Await files(i).Properties.GetImagePropertiesAsync()
' do something with the date the image was taken
Dim dateTaken As DateTimeOffset = imgProps.DateTaken
Next i
Třetí příklad používá QueryOptions k získání informací o sadě souborů. Tento přístup poskytuje mnohem lepší výkon než předchozí příklad.
// Set QueryOptions to prefetch our specific properties
var queryOptions = new Windows.Storage.Search.QueryOptions(CommonFileQuery.OrderByDate, null);
queryOptions.SetThumbnailPrefetch(ThumbnailMode.PicturesView, 100,
ThumbnailOptions.ReturnOnlyIfCached);
queryOptions.SetPropertyPrefetch(PropertyPrefetchOptions.ImageProperties,
new string[] {"System.Size"});
StorageFileQueryResult queryResults = KnownFolders.PicturesLibrary.CreateFileQueryWithOptions(queryOptions);
IReadOnlyList<StorageFile> files = await queryResults.GetFilesAsync();
foreach (var file in files)
{
ImageProperties imageProperties = await file.Properties.GetImagePropertiesAsync();
// Do something with the date the image was taken.
DateTimeOffset dateTaken = imageProperties.DateTaken;
// Performance gains increase with the number of properties that are accessed.
IDictionary<String, object> propertyResults =
await file.Properties.RetrievePropertiesAsync(
new string[] {"System.Size" });
// Get/Set extra properties here
var systemSize = propertyResults["System.Size"];
}
' Set QueryOptions to prefetch our specific properties
Dim queryOptions = New Windows.Storage.Search.QueryOptions(CommonFileQuery.OrderByDate, Nothing)
queryOptions.SetThumbnailPrefetch(ThumbnailMode.PicturesView,
100, Windows.Storage.FileProperties.ThumbnailOptions.ReturnOnlyIfCached)
queryOptions.SetPropertyPrefetch(PropertyPrefetchOptions.ImageProperties,
New String() {"System.Size"})
Dim queryResults As StorageFileQueryResult = KnownFolders.PicturesLibrary.CreateFileQueryWithOptions(queryOptions)
Dim files As IReadOnlyList(Of StorageFile) = Await queryResults.GetFilesAsync()
For Each file In files
Dim imageProperties As ImageProperties = Await file.Properties.GetImagePropertiesAsync()
' Do something with the date the image was taken.
Dim dateTaken As DateTimeOffset = imageProperties.DateTaken
' Performance gains increase with the number of properties that are accessed.
Dim propertyResults As IDictionary(Of String, Object) =
Await file.Properties.RetrievePropertiesAsync(New String() {"System.Size"})
' Get/Set extra properties here
Dim systemSize = propertyResults("System.Size")
Next file
Pokud provádíte více operací s objekty Windows.Storage, jako je Windows.Storage.ApplicationData.Current.LocalFolder, vytvořte místní proměnnou, která bude odkazovat na tento zdroj úložiště, takže při každém přístupu k němu nebudete znovu vytvářet zprostředkující objekty.
Streamování výkonu v jazyce C# a Visual Basic
Ukládání do vyrovnávací paměti mezi datovými proudy UPW a .NET
Existuje mnoho scénářů, kdy můžete chtít převést stream UPW (například Windows.Storage.Streams.IInputStream nebo IOutputStream) na datový proud .NET (System.IO.Stream). To je užitečné například při psaní aplikace pro UPW a chcete použít existující kód .NET, který funguje na datových proudech se systémem souborů UPW. Aby bylo možné tuto možnost povolit, rozhraní .NET API pro aplikace pro UPW poskytují rozšiřující metody, které umožňují převést mezi typy datových proudů .NET a UPW. Další informace najdete v tématu WindowsRuntimeStreamExtensions.
Při převodu datového proudu UPW na datový proud .NET efektivně vytvoříte adaptér pro podkladový datový proud UPW. Za určitých okolností jsou s vyvoláním metod u datových proudů UWP spojeny náklady během běhu. To může mít vliv na rychlost aplikace, zejména ve scénářích, kdy provádíte mnoho malých, častých operací čtení nebo zápisu.
Aby bylo možné urychlit aplikace, obsahují adaptéry datových proudů UPW datovou vyrovnávací paměť. Následující ukázka kódu ukazuje malé po sobě jdoucí čtení pomocí adaptéru streamu UPW s výchozí velikostí vyrovnávací paměti.
StorageFile file = await Windows.Storage.ApplicationData.Current
.LocalFolder.GetFileAsync("example.txt");
Windows.Storage.Streams.IInputStream windowsRuntimeStream =
await file.OpenReadAsync();
byte[] destinationArray = new byte[8];
// Create an adapter with the default buffer size.
using (var managedStream = windowsRuntimeStream.AsStreamForRead())
{
// Read 8 bytes into destinationArray.
// A larger block is actually read from the underlying
// windowsRuntimeStream and buffered within the adapter.
await managedStream.ReadAsync(destinationArray, 0, 8);
// Read 8 more bytes into destinationArray.
// This call may complete much faster than the first call
// because the data is buffered and no call to the
// underlying windowsRuntimeStream needs to be made.
await managedStream.ReadAsync(destinationArray, 0, 8);
}
Dim file As StorageFile = Await Windows.Storage.ApplicationData.Current -
.LocalFolder.GetFileAsync("example.txt")
Dim windowsRuntimeStream As Windows.Storage.Streams.IInputStream =
Await file.OpenReadAsync()
Dim destinationArray() As Byte = New Byte(8) {}
' Create an adapter with the default buffer size.
Dim managedStream As Stream = windowsRuntimeStream.AsStreamForRead()
Using (managedStream)
' Read 8 bytes into destinationArray.
' A larger block is actually read from the underlying
' windowsRuntimeStream and buffered within the adapter.
Await managedStream.ReadAsync(destinationArray, 0, 8)
' Read 8 more bytes into destinationArray.
' This call may complete much faster than the first call
' because the data is buffered and no call to the
' underlying windowsRuntimeStream needs to be made.
Await managedStream.ReadAsync(destinationArray, 0, 8)
End Using
Toto výchozí chování ukládání do vyrovnávací paměti je žádoucí ve většině scénářů, kdy převedete datový proud UWP na datový proud .NET. V některých scénářích můžete chtít upravit chování vyrovnávací paměti, aby se zvýšil výkon.
Práce s velkými datovými sadami
Při čtení nebo zápisu větších sad dat můžete zvýšit propustnost čtení nebo zápisu tím, že AsStreamForRead, AsStreamForWritea AsStream rozšiřující metody. Adaptér datového proudu tak má větší velikost interní vyrovnávací paměti. Například při předávání datového proudu, který pochází z velkého souboru do analyzátoru XML, může analyzátor provádět mnoho sekvenčních malých čtení z datového proudu. Velká vyrovnávací paměť může snížit počet volání základního datového proudu UPW a zvýšit výkon.
Poznámka Při nastavování velikosti výstupní paměti větší než přibližně 80 kB byste měli být opatrní, protože to může způsobit fragmentaci haldy spravované uvolňovačem paměti (viz Zlepšení výkonu uvolňování paměti). Následující příklad kódu vytvoří adaptér spravovaného datového proudu s vyrovnávací pamětí 81 920 bajtů.
// Create a stream adapter with an 80 KB buffer.
Stream managedStream = nativeStream.AsStreamForRead(bufferSize: 81920);
' Create a stream adapter with an 80 KB buffer.
Dim managedStream As Stream = nativeStream.AsStreamForRead(bufferSize:=81920)
Metody Stream.CopyTo a CopyToAsync také přidělují místní vyrovnávací paměť pro kopírování mezi datovými proudy. Stejně jako u metody rozšíření AsStreamForRead lze dosáhnout lepšího výkonu při kopírování velkých datových proudů tím, že přepíšete výchozí velikost vyrovnávací paměti. Následující příklad kódu demonstruje změnu výchozí velikosti vyrovnávací paměti při volání metody CopyToAsync.
MemoryStream destination = new MemoryStream();
// copies the buffer into memory using the default copy buffer
await managedStream.CopyToAsync(destination);
// Copy the buffer into memory using a 1 MB copy buffer.
await managedStream.CopyToAsync(destination, bufferSize: 1024 * 1024);
Dim destination As MemoryStream = New MemoryStream()
' copies the buffer into memory using the default copy buffer
Await managedStream.CopyToAsync(destination)
' Copy the buffer into memory using a 1 MB copy buffer.
Await managedStream.CopyToAsync(destination, bufferSize:=1024 * 1024)
Tento příklad používá velikost vyrovnávací paměti 1 MB, která je větší než 80 kB dříve doporučená. Použití takové velké vyrovnávací paměti může zlepšit propustnost operace kopírování pro velmi velké datové sady (to znamená několik stovek megabajtů). Tato vyrovnávací paměť je však přidělena na haldu velkého objektu a může snížit výkon správy paměti. Velké velikosti vyrovnávací paměti byste měli používat jenom v případě, že výrazně zlepší výkon vaší aplikace.
Při práci se současným velkým počtem datových proudů možná budete chtít snížit nebo odstranit náročnost na paměť bufferu. Můžete zadat menší vyrovnávací paměť nebo nastavit parametr bufferSize na hodnotu 0 k úplnému vypnutí ukládání do vyrovnávací paměti pro tento adaptér datového proudu. Pokud provádíte velké čtení a zápisy do spravovaného datového proudu, můžete i tak dosáhnout dobrého výkonu propustnosti bez ukládání do vyrovnávací paměti.
Provádění operací citlivých na latenci
Také byste se mohli vyhnout používání vyrovnávací paměti, pokud chcete čtení a zápisy s nízkou latencí a nechcete číst ve velkých blocích ze základního datového proudu UWP. Pokud například používáte datový proud pro síťovou komunikaci, můžete chtít čtení a zápisy s nízkou latencí.
V chatovací aplikaci můžete použít stream přes síťové rozhraní k odesílání zpráv zpět a zpět. V takovém případě chcete odesílat zprávy hned, jak jsou připravené, a nečekat na vyplnění vyrovnávací paměti. Pokud nastavíte velikost vyrovnávací paměti na 0 při volání AsStreamForRead, AsStreamForWritea AsStream rozšiřující metody, výsledný adaptér nepřidělí vyrovnávací paměť a všechna volání budou manipulovat s podkladovým proudem UPW přímo.