Delen via


Wijzigingen in het bestandssysteem op de achtergrond bijhouden

Belangrijke API's

Met de StorageLibraryChangeTracker klasse kunnen apps wijzigingen in bestanden en mappen bijhouden wanneer gebruikers ze door het systeem verplaatsen. Met behulp van de klasse StorageLibraryChangeTracker kan een app het volgende bijhouden:

  • Bestandsbewerkingen, waaronder toevoegen, verwijderen, wijzigen.
  • Mapbewerkingen, zoals hernoemingen en verwijderingen.
  • Bestanden en mappen verplaatsen op de schijf.

Gebruik deze handleiding voor meer informatie over het programmamodel voor het werken met de wijzigingentracker, bekijk enkele voorbeeldcode en begrijp de verschillende typen bestandsbewerkingen die worden bijgehouden door StorageLibraryChangeTracker.

StorageLibraryChangeTracker- werkt voor gebruikersbibliotheken of voor een map op de lokale computer. Dit omvat secundaire stations of verwisselbare stations, maar bevat geen NAS-stations of netwerkstations.

De wijzigingstracker gebruiken

De wijzigingstracker wordt op het systeem geïmplementeerd als een circulaire buffer die de laatste N bestandssysteembewerkingen opslaat. Apps kunnen de wijzigingen van de buffer lezen en ze vervolgens verwerken in hun eigen ervaringen. Zodra de app is voltooid met de wijzigingen, worden de wijzigingen gemarkeerd als verwerkt en worden ze nooit meer weergegeven.

Volg deze stappen om de wijzigingstracker in een map te gebruiken:

  1. Schakel het bijhouden van wijzigingen in voor de map.
  2. Wacht op wijzigingen.
  3. Wijzigingen lezen.
  4. Accepteer wijzigingen.

In de volgende secties worden alle stappen beschreven met enkele codevoorbeelden. Het volledige codevoorbeeld vindt u aan het einde van het artikel.

De wijzigingstracker inschakelen

Het eerste wat de app moet doen, is het systeem vertellen dat het geïnteresseerd is in het bijhouden van wijzigingen in een bepaalde bibliotheek. Dit doe je door de methode Enable aan te roepen op de wijzigingstracker voor de gewenste bibliotheek.

StorageLibrary videosLib = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Videos);
StorageLibraryChangeTracker videoTracker = videosLib.ChangeTracker;
videoTracker.Enable();

Enkele belangrijke opmerkingen:

  • Zorg ervoor dat uw app gemachtigd is voor de juiste bibliotheek in het manifest voordat u het StorageLibrary--object maakt. Zie machtigingen voor bestandstoegang voor meer informatie.
  • Inschakelen is thread-veilig, zal je aanwijzer niet resetten en kan zo vaak worden aangeroepen als je wilt (meer hierover later).

een lege wijzigingstracker inschakelen

Wachten op wijzigingen

Nadat de wijzigingstracker is geïnitialiseerd, worden alle bewerkingen vastgelegd die zich in een bibliotheek voordoen, zelfs als de app niet wordt uitgevoerd. Apps kunnen worden geregistreerd om te worden geactiveerd wanneer er een wijziging is door registratie voor de StorageLibraryChangedTrigger gebeurtenis.

Wijzigingen die worden toegevoegd aan de wijzigingentracker zonder dat de app ze leest

De wijzigingen lezen

De app kan vervolgens peilen naar wijzigingen van de wijzigingentracker en een lijst met de wijzigingen ontvangen sinds de laatste keer dat deze is gecontroleerd. De onderstaande code laat zien hoe u een lijst met wijzigingen kunt ophalen van de wijzigingentracker.

StorageLibrary videosLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Videos);
videosLibrary.ChangeTracker.Enable();
StorageLibraryChangeReader videoChangeReader = videosLibrary.ChangeTracker.GetChangeReader();
IReadOnlyList changeSet = await changeReader.ReadBatchAsync();

De app is vervolgens indien nodig verantwoordelijk voor het verwerken van de wijzigingen in zijn eigen ervaring of database.

De wijzigingen van de wijzigingenvolger naar een app-database overbrengen

Aanbeveling

De tweede aanroep om in te schakelen is om zich te verdedigen tegen een raceconditie als de gebruiker een andere map aan de bibliotheek toevoegt terwijl uw app wijzigingen leest. Zonder de extra aanroep van Inschakelen mislukt de code met ecSearchFolderScopeViolation (0x80070490) als de gebruiker de mappen in de bibliotheek wijzigt

De wijzigingen accepteren

Nadat de app klaar is met het verwerken van de wijzigingen, moet het systeem de wijzigingen nooit meer laten zien door de methode AcceptChangesAsync aan te roepen.

await changeReader.AcceptChangesAsync();

Wijzigingen markeren als gelezen, zodat ze nooit meer worden weergegeven

De app ontvangt nu alleen nieuwe wijzigingen wanneer de wijzigingentracker in de toekomst wordt gelezen.

  • Als er wijzigingen zijn aangebracht tussen het aanroepen van ReadBatchAsync- en AcceptChangesAsync, wordt de aanwijzer alleen geavanceerd naar de meest recente wijziging die de app heeft gezien. Deze andere wijzigingen zijn nog steeds beschikbaar wanneer deze de volgende keer ReadBatchAsync-aanroept.
  • Als u de wijzigingen niet accepteert, zal het systeem dezelfde set wijzigingen retourneren wanneer de app de volgende keer ReadBatchAsyncaanroept.

Belangrijke dingen die u moet onthouden

Wanneer u de wijzigingentracker gebruikt, moet u rekening houden met een paar dingen om ervoor te zorgen dat alles correct werkt.

Bufferoverschrijdingen

Hoewel we proberen voldoende ruimte te reserveren in de wijzigingstracker om alle bewerkingen op het systeem vast te houden totdat uw app ze kan lezen, is het heel gemakkelijk om een scenario te bedenken waarin de app de wijzigingen niet leest voordat de kringbuffer zichzelf overschrijft. Vooral als de gebruiker gegevens herstelt vanuit een back-up of een grote verzameling foto's synchroniseert vanaf de cameratelefoon.

In dit geval retourneert ReadBatchAsync de foutcode StorageLibraryChangeType.ChangeTrackingLost. Als uw app deze foutcode ontvangt, betekent dit een aantal dingen:

  • De buffer heeft zichzelf overschreven sinds de laatste keer dat u deze hebt bekeken. De beste manier van handelen is om de bibliotheek opnieuw te verkennen, omdat alle informatie van de tracker onvolledig is.
  • De wijzigingentracker zal geen wijzigingen meer retourneren totdat u Resetaanroept. Nadat de app-aanroepen opnieuw zijn ingesteld, wordt de aanwijzer verplaatst naar de meest recente wijziging en wordt het bijhouden normaal hervat.

Het moet zeldzaam zijn dat deze gevallen voorkomen, maar in scenario's waarin de gebruiker een groot aantal bestanden op zijn schijf verplaatst, willen we niet dat de wijzigingstracker uitgroeit en te veel opslagruimte in beslag neemt. Hierdoor kunnen apps reageren op enorme bestandssysteembewerkingen, terwijl de klantervaring in Windows niet wordt beschadigd.

Wijzigingen in een StorageLibrary

De StorageLibrary-klasse bestaat als een virtuele groep hoofdmappen die andere mappen bevatten. Om dit af te stemmen met een tracker voor wijzigingen in een bestandssysteem, hebben we de volgende keuzes gemaakt:

  • Wijzigingen in afstamming van de hoofdbibliotheekmappen worden weergegeven in de wijzigingentracker. De hoofdbibliotheekmappen vindt u met behulp van de eigenschap Mappen.
  • Als u hoofdmappen toevoegt aan of verwijdert uit een StorageLibrary- (via RequestAddFolderAsync- en RequestRemoveFolderAsync) wordt er geen vermelding gemaakt in de wijzigingentracker. Deze wijzigingen kunnen worden bijgehouden via de gebeurtenis DefinitionChanged of door de hoofdmappen in de bibliotheek op te sommen met behulp van de eigenschap Mappen.
  • Als er al een map met inhoud is toegevoegd aan de bibliotheek, wordt er geen wijzigingsmelding of wijzigingstrackervermeldingen gegenereerd. Eventuele latere wijzigingen in de afstammelingen van die map zullen meldingen en wijzigingstrackervermeldingen genereren.

De Inschakelen-methode oproepen

Apps moeten Inschakelen aanroepen zodra ze beginnen met het bijhouden van het bestandssysteem en vóór elke opsomming van de wijzigingen. Dit zorgt ervoor dat alle wijzigingen worden vastgelegd door de wijzigingentracker.

Alles samenbrengen

Hier ziet u alle code die wordt gebruikt om u te registreren voor de wijzigingen uit de videobibliotheek en de wijzigingen op te halen uit de wijzigingentracker.

private async void EnableChangeTracker()
{
    StorageLibrary videosLib = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Videos);
    StorageLibraryChangeTracker videoTracker = videosLib.ChangeTracker;
    videoTracker.Enable();
}

private async void GetChanges()
{
    StorageLibrary videosLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Videos);
    videosLibrary.ChangeTracker.Enable();
    StorageLibraryChangeReader videoChangeReader = videosLibrary.ChangeTracker.GetChangeReader();
    IReadOnlyList changeSet = await changeReader.ReadBatchAsync();


    //Below this line is for the blog post. Above the line is for the magazine
    foreach (StorageLibraryChange change in changeSet)
    {
        if (change.ChangeType == StorageLibraryChangeType.ChangeTrackingLost)
        {
            //We are in trouble. Nothing else is going to be valid.
            log("Resetting the change tracker");
            videosLibrary.ChangeTracker.Reset();
            return;
        }
        if (change.IsOfType(StorageItemTypes.Folder))
        {
            await HandleFileChange(change);
        }
        else if (change.IsOfType(StorageItemTypes.File))
        {
            await HandleFolderChange(change);
        }
        else if (change.IsOfType(StorageItemTypes.None))
        {
            if (change.ChangeType == StorageLibraryChangeType.Deleted)
            {
                RemoveItemFromDB(change.Path);
            }
        }
    }
    await changeReader.AcceptChangesAsync();
}