2008-09-11 7 views
17

Es gibt viele Beiträge im Internet über die ReadDirectoryChangesW API-Funktion fehlende Dateien, wenn es viele Dateiaktivitäten gibt. Die meisten beschuldigen die Geschwindigkeit, mit der die ReadDirectoryChangesW-Funktionsschleife aufgerufen wird. Dies ist eine falsche Annahme. Die beste Erklärung, die ich habe in dem folgenden Beitrag gesehen ist, der Kommentar am Montag, 14. April 2008 02.15.27Wie man ReadDirectoryChangesW vor fehlenden Dateiänderungen bewahrt

http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/4465cafb-f4ed-434f-89d8-c85ced6ffaa8/

Die Zusammenfassung ist, dass die ReadDirectoryChangesW Funktion Bericht Änderungen Datei, wie sie das verlassen Datei-Write-Behind-Warteschlange, nicht wie sie hinzugefügt werden. Und wenn zu viele hinzugefügt werden, bevor Sie verpflichtet werden, verlieren Sie die Benachrichtigung über einige von ihnen. Sie können dies mit Ihrer Implementierung sehen, wenn Sie nur ein Programm schreiben, um schnell 1000+ Dateien in einem Verzeichnis zu generieren. Zählen Sie einfach, wie viele Ereignisbenachrichtigungen Sie erhalten, und Sie werden sehen, dass es Zeiten gibt, zu denen Sie nicht alle erhalten.

Die Frage ist, hat jemand eine zuverlässige Methode gefunden, um die Funktion ReadDirectoryChangesW zu verwenden, ohne das Volumen jedes Mal zu leeren? Dies ist nicht zulässig, wenn der Benutzer kein Administrator ist und auch etwas Zeit zum Ausführen benötigt.

Antwort

1

Wenn die API unzuverlässig ist, ist möglicherweise eine Problemumgehung die einzige Option. Das beinhaltet natürlich die Verfolgung von zuletzt geänderten Dateinamen und Dateinamen. Was dies nicht bedeutet, dass Sie abfragen müssen, wenn Sie nach Änderungen suchen, stattdessen können Sie den FileSystemWatcher als Mittel verwenden, um die Überprüfung auszulösen.

Also, wenn Sie den Überblick über die letzten 50 bis 100-fache der ReadDirectoryChangesW /FSW Ereignis passiert, und Sie sehen, dass es schnell aufgerufen wird, können Sie dies erkennen und die besondere Bedingung auslösen, alle Dateien zu erhalten die geändert wurden (und eine Markierung setzen, um zukünftige gefälschte FSW-Ereignisse vorübergehend zu verhindern) in ein paar Sekunden. Da einige Leute in den Kommentaren zu dieser Lösung verwirrt sind, schlage ich vor, dass Sie überwachen sollten, wie schnell Ereignisse vom ReadDirectoryChangesW kommen. Wenn sie zu schnell ankommen, versuchen Sie eine Abhilfe zu versuchen (normalerweise ein manueller Durchlauf von ein Verzeichnis).

+1

Dies würde für etwa 99% der Zeit funktionieren. Was passiert, wenn eine Datei in einem anderen Verzeichnis (außer dem mit vielen Dateiänderungen) übersprungen wird? Sie würden das eine Verzeichnis nach Änderungen durchsuchen, aber die Änderung der einzelnen Datei in einem anderen Verzeichnis verpassen. –

+0

Die FileSystemWatcher-Klasse ist eine .NET-Methode zum Umbrechen von ReadDirectoryChangesW, also nein, das hilft nicht. – Garen

+0

Meine Antwort war mehr über das Erkennen der # von Ereignissen innerhalb eines Zeitraums, um die Problemumgehung für ReadDirectoryChangesW auszulösen. – hova

0

Ich traf das gleiche Problem. Aber ich habe keine Lösung gefunden, die alle Ereignisse garantiert. In mehreren Tests konnte ich wissen, dass die ReadDirectoryChangesW-Funktion so schnell wie möglich erneut aufgerufen werden sollte, nachdem die GetQueuedCompletionStatus-Funktion zurückgegeben wurde. Ich denke, wenn eine Verarbeitungsgeschwindigkeit des Dateisystems sehr viel schneller ist als meine Anwendungsverarbeitungsgeschwindigkeit, kann die Anwendung möglicherweise einige Ereignisse verlieren.

Jedenfalls habe ich eine Parsing-Logik von einer Überwachungslogik getrennt und eine Parsing-Logik in einen Thread eingefügt.

+0

Ich habe das Problem mit etwas Ähnlichem erfolgreich gelöst. Legen Sie die Ereignisse in eine Warteschlange oder schreiben Sie sie zur späteren Verarbeitung in eine Datei. Sie auf die Festplatte zu schreiben war der Schlüssel für mich. Das mag langsam erscheinen, aber Festplatten werden zwischengespeichert und der Overhead ist kleiner als ein DB. Mein Programm spiegelt etwa 1 TB pro Tag Dateiänderungen wider - Hunderttausende von Dateien pro Tag. – SilentSteel

1

Wir haben noch nie gesehen, dass ReadDirectoryChangesW zu 100% zuverlässig ist. Aber die beste Art, damit umzugehen, ist das "Berichten" von der "Handhabung" zu trennen.

Meine Implementierung hat einen Thread, der nur einen Job hat, um alle Ereignisse neu zu ordnen. Dann ein zweiter Thread, um meine Zwischenwarteschlange zu verarbeiten. Sie wollen grundsätzlich die Berichterstattung über Ereignisse so wenig wie möglich behindern.

In hohen CPU-Situationen können Sie auch das Melden von Watcher-Ereignissen verhindern.

+0

Da ich nicht genug Reputation habe, um oben zu kommentieren, werde ich sagen, dass die Top-Lösung sehr gut ist. In 99% der Fälle sind Sie "fast da". Fügen Sie eine weitere Sache hinzu, eine periodische Gesamtresultate der Ordner, die Sie beobachten, um nach Änderungen zu suchen. – Lompican

Verwandte Themen