Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Maak UWP-apps (Universal Windows Platform) die efficiënt toegang hebben tot het bestandssysteem, waardoor prestatieproblemen worden vermeden vanwege schijflatentie en geheugen-/CPU-cycli.
Als u toegang wilt krijgen tot een grote verzameling bestanden en u andere eigenschapswaarden wilt openen dan de typische eigenschappen Name, FileType en Path, opent u deze door QueryOptions- te maken en SetPropertyPrefetchaan te roepen. De methode SetPropertyPrefetch kan de prestaties van apps die een verzameling items weergeven die zijn verkregen uit het bestandssysteem, zoals een verzameling afbeeldingen, aanzienlijk verbeteren. In de volgende reeks voorbeelden ziet u een aantal manieren om toegang te krijgen tot meerdere bestanden.
In het eerste voorbeeld wordt Windows.Storage.StorageFolder.GetFilesAsync gebruikt om de naamgegevens voor een set bestanden op te halen. Deze benadering biedt goede prestaties, omdat het voorbeeld alleen toegang heeft tot de naameigenschap.
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
In het tweede voorbeeld wordt Windows.Storage.StorageFolder.GetFilesAsync gebruikt en worden vervolgens de afbeeldingseigenschappen voor elk bestand opgehaald. Deze aanpak biedt slechte prestaties.
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
In het derde voorbeeld wordt QueryOptions- gebruikt om informatie over een set bestanden op te halen. Deze benadering biedt veel betere prestaties dan in het vorige voorbeeld.
// 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
Als u meerdere bewerkingen uitvoert op Windows.Storage-objecten zoals Windows.Storage.ApplicationData.Current.LocalFolder, maak dan een lokale variabele om naar die opslagbron te verwijzen. Zo voorkomt u dat u iedere keer wanneer u toegang nodig heeft, tussenliggende objecten opnieuw moet creëren.
Streamprestaties in C# en Visual Basic
Bufferen tussen UWP- en .NET-streams
Er zijn veel scenario's waarin u een UWP-stroom (zoals een Windows.Storage.Streams.IInputStream of IOutputStream) wilt converteren naar een .NET-stream (System.IO.Stream). Dit is bijvoorbeeld handig wanneer u een UWP-app schrijft en bestaande .NET-code wilt gebruiken die werkt op streams met het UWP-bestandssysteem. Om dit in te schakelen, bieden .NET-API's voor UWP-apps extensiemethoden waarmee u kunt converteren tussen .NET- en UWP-stroomtypen. Zie WindowsRuntimeStreamExtensionsvoor meer informatie.
Wanneer u een UWP-stroom converteert naar een .NET-stream, maakt u effectief een adapter voor de onderliggende UWP-stroom. Onder bepaalde omstandigheden zijn er runtimekosten gekoppeld aan het aanroepen van methoden op UWP-streams. Dit kan van invloed zijn op de snelheid van uw app, met name in scenario's waarin u veel kleine, frequente lees- of schrijfbewerkingen uitvoert.
Om apps sneller te maken, bevatten de UWP-stroomadapters een gegevensbuffer. In het volgende codevoorbeeld ziet u kleine opeenvolgende leesbewerkingen met behulp van een UWP-stroomadapter met een standaardbuffergrootte.
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
Dit standaardbuffergedrag is wenselijk in de meeste scenario's waarin u een UWP-stroom converteert naar een .NET-stream. In sommige scenario's kunt u echter het buffergedrag aanpassen om de prestaties te verbeteren.
Werken met grote gegevenssets
Wanneer u grotere gegevenssets leest of schrijft, kunt u mogelijk de lees- of schrijfdoorvoer verhogen door een grote buffergrootte te bieden aan de AsStreamForRead-, AsStreamForWrite-en AsStream uitbreidingsmethoden. Hierdoor krijgt de streamadapter een grotere interne buffergrootte. Wanneer u bijvoorbeeld een stroom doorgeeft die afkomstig is van een groot bestand naar een XML-parser, kan de parser veel opeenvolgende kleine leesbewerkingen van de stream maken. Een grote buffer kan het aantal aanroepen naar de onderliggende UWP-stroom verminderen en de prestaties verbeteren.
Opmerking U moet voorzichtig zijn bij het instellen van een buffergrootte die groter is dan ongeveer 80 kB, omdat dit fragmentatie op de garbagecollection heap kan veroorzaken (zie Prestaties van garbagecollection verbeteren). In het volgende codevoorbeeld wordt een beheerde streamadapter gemaakt met een 81.920 bytebuffer.
// 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)
De methoden Stream.CopyTo en CopyToAsync wijzen ook een lokale buffer toe voor het kopiëren tussen streams. Net als bij de extensiemethode AsStreamForRead, kunt u mogelijk betere prestaties krijgen voor grote streamkopieën door de standaardbuffergrootte te overschrijven. In het volgende codevoorbeeld ziet u hoe u de standaardbuffergrootte van een CopyToAsync aanroep wijzigt.
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)
In dit voorbeeld wordt een buffergrootte van 1 MB gebruikt, die groter is dan de 80 kB die eerder is aanbevolen. Door een dergelijke grote buffer te gebruiken, kan de doorvoer van de kopieerbewerking voor zeer grote gegevenssets (dat wil gezegd enkele honderden megabytes) verbeteren. Deze buffer wordt echter toegewezen op de grote object-heap en kan mogelijk de prestaties van de garbagecollectie verminderen. Gebruik alleen grote buffergrootten als de prestaties van uw app aanzienlijk worden verbeterd.
Wanneer u tegelijkertijd met een groot aantal streams werkt, kunt u de geheugenoverhead van de buffer verminderen of elimineren. U kunt een kleinere buffer opgeven of de parameter bufferSize instellen op 0 om buffering volledig uit te schakelen voor die stroomadapter. U kunt nog steeds goede doorvoerprestaties bereiken zonder buffering als u grote lees- en schrijfbewerkingen naar de beheerde stream uitvoert.
Latentiegevoelige bewerkingen uitvoeren
U kunt ook buffering voorkomen als u lees- en schrijfbewerkingen met lage latentie wilt en niet wilt lezen in grote blokken uit de onderliggende UWP-stroom. U wilt bijvoorbeeld lees- en schrijfbewerkingen met lage latentie als u de stream voor netwerkcommunicatie gebruikt.
In een chat-app kunt u een stream via een netwerkinterface gebruiken om berichten heen en weer te verzenden. In dit geval wilt u berichten verzenden zodra ze klaar zijn en niet wachten totdat de buffer vol is. Als u de buffergrootte instelt op 0 bij het aanroepen van de AsStreamForRead-, AsStreamForWriteen AsStream extensiemethoden, wijst de resulterende adapter geen buffer toe en worden alle aanroepen de onderliggende UWP-stroom rechtstreeks bewerkt.