Freigeben über


Nachverfolgen von Dateisystemänderungen im Hintergrund

Wichtige APIs

Die StorageLibraryChangeTracker-Klasse ermöglicht Apps das Nachverfolgen von Änderungen in Dateien und Ordnern, wenn Benutzer sie um das System verschieben. Mithilfe der StorageLibraryChangeTracker-Klasse kann eine App Folgendes nachverfolgen:

  • Dateivorgänge, einschließlich Hinzufügen, Löschen, Ändern.
  • Ordnervorgänge wie Umbenennen und Löschen.
  • Dateien und Ordner, die auf dem Laufwerk verschoben werden.

Verwenden Sie dieses Handbuch, um das Programmiermodell für die Arbeit mit der Änderungsverfolgung zu erlernen, beispielcode anzuzeigen und die verschiedenen Arten von Dateivorgängen zu verstehen, die von StorageLibraryChangeTracker nachverfolgt werden.

StorageLibraryChangeTracker funktioniert für Benutzerbibliotheken oder für einen beliebigen Ordner auf dem lokalen Computer. Dazu gehören sekundäre Laufwerke oder Wechseldatenträger, aber keine NAS-Laufwerke oder Netzwerklaufwerke.

Verwenden der Änderungsverfolgung

Die Änderungsverfolgung wird auf dem System als Zirkularpuffer implementiert, der die letzten N Dateisystem-Vorgänge speichert. Apps können die Änderungen aus dem Puffer lesen und dann in ihre eigenen Erfahrungen verarbeiten. Sobald die App mit den Änderungen fertig ist, markiert sie diese als verarbeitet und wird sie nie wieder sehen.

Führen Sie die folgenden Schritte aus, um die Änderungsverfolgung für einen Ordner zu verwenden:

  1. Aktivieren Sie die Änderungsnachverfolgung für den Ordner.
  2. Warten Sie auf Änderungen.
  3. Änderungen lesen.
  4. Änderungen annehmen.

In den nächsten Abschnitten werden die einzelnen Schritte mit einigen Codebeispielen erläutert. Das vollständige Codebeispiel wird am Ende des Artikels bereitgestellt.

Aktivieren der Änderungsverfolgung

Als Erstes muss die App dem System mitteilen, dass sie am Tracking von Änderungen in einer bestimmten Bibliothek interessiert ist. Dies geschieht durch Aufrufen der Enable-Methode für die Änderungsverfolgung für die Bibliothek von Interesse.

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

Einige wichtige Hinweise:

  • Stellen Sie sicher, dass Ihre App über die Berechtigung für die richtige Bibliothek im Manifest verfügt, bevor Sie das StorageLibrary-Objekt erstellen. Weitere Informationen finden Sie unter "Dateizugriffsberechtigungen ".
  • "Aktivieren" ist threadsicher, setzt den Zeiger nicht zurück und kann so oft aufgerufen werden, wie Sie möchten (mehr dazu später).

Aktivieren eines leeren Änderungstrackers

Auf Änderungen warten

Nachdem die Änderungsverfolgung initialisiert wurde, beginnt sie, alle Vorgänge aufzuzeichnen, die in einer Bibliothek auftreten, auch wenn die App nicht ausgeführt wird. Apps können sich registrieren, damit sie bei jeder Änderung aktiviert werden können, indem sie sich für das Ereignis StorageLibraryChangedTrigger registrieren.

Änderungen, die der Änderungsverfolgung hinzugefügt werden, ohne dass die App sie liest

Änderungen lesen

Die App kann dann Änderungen aus der Änderungsverfolgung abrufen und eine Liste der Änderungen seit der letzten Überprüfung erhalten. Der folgende Code zeigt, wie Sie eine Liste der Änderungen aus der Änderungsverfolgung abrufen.

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

Die App ist dann für die Verarbeitung der Änderungen in die eigene Benutzeroberfläche oder Datenbank nach Bedarf verantwortlich.

Lesen der Änderungen aus der Änderungsverfolgung in eine App-Datenbank

Tipp

Der zweite Aufruf zur Aktivierung besteht darin, sich gegen eine Race Condition zu verteidigen, wenn der Benutzer der Library einen anderen Ordner hinzufügt, während Ihre App Änderungen liest. Ohne den zusätzlichen Aufruf von Enable schlägt der Code mit ecSearchFolderScopeViolation (0x80070490) fehl, wenn der Benutzer die Ordner in seiner Bibliothek ändert.

Übernehmen der Änderungen

Nachdem die App die Verarbeitung der Änderungen abgeschlossen hat, sollte das System anweisen, diese Änderungen nie wieder anzuzeigen, indem die AcceptChangesAsync-Methode aufgerufen wird.

await changeReader.AcceptChangesAsync();

Markieren von Änderungen als gelesen, sodass sie nie wieder angezeigt werden

Die App erhält jetzt nur noch neue Änderungen, wenn der Änderungstracker gelesen wird.

  • Wenn Änderungen zwischen dem Aufrufen von ReadBatchAsync und AcceptChangesAsync vorgenommen wurden, wird der Zeiger nur zur letzten Änderung erweitert, die die App gesehen hat. Diese anderen Änderungen sind beim nächsten Aufrufen von ReadBatchAsync weiterhin verfügbar.
  • Wenn Sie die Änderungen nicht akzeptieren, gibt das System beim nächsten Aufruf von ReadBatchAsync denselben Satz von Änderungen zurück.

Wichtige Dinge, die Sie sich merken sollten

Wenn Sie den Änderungstracker verwenden, sollten Sie einige Dinge beachten, um sicherzustellen, dass alles ordnungsgemäß funktioniert.

Pufferüberläufe

Obwohl wir versuchen, genügend Platz in der Änderungsverfolgung zu reservieren, um alle Vorgänge im System zu speichern, bis Ihre App sie lesen kann, ist es sehr einfach, ein Szenario vorzustellen, in dem die App die Änderungen nicht vorliest, bevor der Kreispuffer sich selbst überschreibt. Insbesondere, wenn der Benutzer Daten aus einer Sicherung wiederherstellen oder eine große Sammlung von Bildern von ihrem Kameratelefon synchronisiert.

In diesem Fall gibt ReadBatchAsync den Fehlercode StorageLibraryChangeType.ChangeTrackingLost zurück. Wenn Ihre App diesen Fehlercode empfängt, bedeutet dies ein paar Dinge:

  • Der Puffer hat sich seit Ihrer letzten Überprüfung überschrieben. Die beste Vorgehensweise besteht darin, die Bibliothek erneut zu durchforsten, da alle Informationen aus dem Tracker unvollständig sind.
  • Die Änderungsverfolgung gibt keine weiteren Änderungen zurück, bis Sie Zurücksetzen aufrufen. Nachdem die App reset aufgerufen hat, wird der Zeiger auf die letzte Änderung verschoben und die Nachverfolgung normal fortgesetzt.

Es sollte selten vorkommen, dass solche Fälle auftreten, aber in Szenarien, in denen der Benutzer eine große Anzahl von Dateien auf seinem Datenträger verschiebt, sollte der Änderungstracker nicht zu groß werden und nicht zu viel Speicherplatz belegen. Dies sollte Apps ermöglichen, auf massive Dateisystemvorgänge zu reagieren, während die Kundenerfahrung in Windows nicht beschädigt wird.

Änderungen an einer StorageLibrary

Die StorageLibrary-Klasse ist als virtuelle Gruppe von Stammordnern vorhanden, die andere Ordner enthalten. Um dies mit einem Dateisystemänderungs-Tracker in Einklang zu bringen, haben wir die folgenden Entscheidungen getroffen:

  • Alle Änderungen an Unterordnern der Stammordner der Bibliothek werden im Änderungstracker dargestellt. Die Stammbibliotheksordner finden Sie mithilfe der Folders-Eigenschaft .
  • Das Hinzufügen oder Entfernen von Stammordnern aus einer StorageLibrary (über RequestAddFolderAsync und RequestRemoveFolderAsync) erstellt keinen Eintrag in der Änderungsverfolgung. Diese Änderungen können über das DefinitionChanged-Ereignis nachverfolgt werden oder indem sie die Stammordner in der Bibliothek mithilfe der Folders-Eigenschaft aufzählen.
  • Wenn ein Ordner mit bereits darin enthaltenem Inhalt der Bibliothek hinzugefügt wird, wird keine Änderungsbenachrichtigung oder Änderungsverfolgungseinträge generiert. Alle nachfolgenden Änderungen an den Nachfolgern dieses Ordners generieren Benachrichtigungen und Änderungsverfolgungseinträge.

Aufrufen der Enable-Methode

Apps sollten "Enable" aufrufen, sobald sie mit der Nachverfolgung des Dateisystems und vor jeder Enumeration der Änderungen beginnen. Dadurch wird sichergestellt, dass alle Änderungen von der Änderungsverfolgungsfunktion erfasst werden.

Alles zusammenbringen

Hier ist der gesamte Code, der verwendet wird, um sich für Änderungen in der Videobibliothek zu registrieren und das Abrufen der Änderungen über den Change-Tracker zu starten.

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();
}