Von MSDN:
Das Windows-Betriebssystem benachrichtigt Ihr Komponente über Dateiänderungen in einem vom FileSystemWatcher erstellten Puffer. Wenn es viele Änderungen in kurzer Zeit gibt, kann der Puffer überlaufen. Dies führt dazu, dass die Komponente den Überblick über Änderungen im Verzeichnis verliert und nur eine allgemeine Benachrichtigung bereitstellt. Das Erhöhen der Größe des Puffers mit der InternalBufferSize-Eigenschaft ist teuer, da er aus nicht auszulagerndem Speicher stammt. Halten Sie den Puffer also klein, aber groß genug, um keine Dateiänderungsereignisse zu verpassen. Um ein Pufferüberlauf zu vermeiden, verwenden Sie die Eigenschaften NotifyFilter und IncludeSubdirectories, um unerwünschte Änderungsbenachrichtigungen herauszufiltern.
Wenn das Erhöhen der Puffergröße nicht ausreicht und Sie nicht steuern können, wie viele Dateien gleichzeitig Ereignisse auslösen, müssten Sie zusätzliches Polling hinzufügen.
Sehen Sie auch diese verwandte Frage:
FileSystemWatcher funktioniert nicht richtig, wenn viele Dateien gleichzeitig zum Verzeichnis hinzugefügt werden…
Aktualisierung:
Es könnte verlockend sein, einfach die Puffergröße zu erhöhen, aber dies sollte mit Vorsicht geschehen. Tatsächlich gibt es eine 64-KB-Beschränkung für den Netzwerkzugriff. Die Klasse FileSystemWatcher
verwendet die Windows-API-Funktion ReadDirectoryChangesW
, die diese Grenze hat:
ReadDirectoryChangesW schlägt mit ERROR_INVALID_PARAMETER fehl, wenn die Pufferlänge größer als 64 KB ist und die Anwendung ein Verzeichnis über das Netzwerk überwacht. Dies liegt an einer Paketgrößenbeschränkung der zugrunde liegenden Dateifreigabeprotokolle.
Wenn Sie ein tieferes Verständnis der Kosten für die Änderung der Puffergröße wünschen, sollten Sie den Beitrag von Walter Wang von Microsoft hier lesen:
FileSystemWatcher über das Netzwerk (voller Beitrag unten zitiert)
Es tut mir leid, dass die Dokumentation von FileSystemWatcher.InternalBufferSize nicht sehr deutlich über die Puffergröße beim Überwachen von Netzwerkpfaden informiert. Es wird empfohlen, nicht mehr als 64K zu überschreiten, wenn ein Netzwerkpfad überwacht wird.
FileSystemWatcher ist im Grunde eine .Net-Umwicklung für die Win32 ReadDirectoryChangesW-API. Um ReadDirectoryChangesW zu verwenden, erstellen und geben Sie einen Puffer an, den das Betriebssystem mit den Änderungen füllen wird. Was jedoch nicht in der ReadDirectoryChangesW-Dokumentation erwähnt wird (aber in der FileSystemWatcher-Dokumentation angedeutet wird), ist dass das Dateisystem einen internen Kernelpuffer erstellt, um die Änderungsinformationen temporär zu speichern, bis es die Chance hat, den Benutzerpuffer zu aktualisieren. Die Größe des erstellten Kernelpuffers entspricht der in ReadDirectoryChangesW angegebenen Größe und wird im nicht ausgelagerten Pool-Speicher erstellt. Jedes Mal, wenn ein FileSystemWatcher / ReadDirectoryChangesW erstellt / aufgerufen wird, wird auch ein neuer Kernelpuffer erstellt.
Die Kernel-Speicher-Pools (ausgelagert und nicht ausgelagert) werden im Systemadressraum für Gerätetreiber und andere Kernelkomponenten reserviert. Sie wachsen und schrumpfen dynamisch, wie es erforderlich ist. Die aktuellen Größen der Pools können einfach im Leistungs-Tab des Task-Managers eingesehen werden. Die Pools werden dynamisch wachsen, bis sie einen maximalen Wert erreichen, der beim Booten berechnet wird und von den verfügbaren Systemressourcen (hauptsächlich RAM) abhängt. Sie möchten diesen maximalen Wert nicht erreichen, da sonst verschiedene Systemdienste und Treiber ausfallen werden. Der berechnete maximale Wert ist jedoch nicht leicht verfügbar. Um die maximalen Poolgrößen zu bestimmen, müssen Sie einen Kernel-Debugger verwenden. Wenn Sie an weiteren Informationen über die Speicherpools des Systems interessiert sind, empfehle ich Ihnen, das Kapitel 7 des MSPress-Buchs Inside Windows 2000 von Solomon und Russinovich zu studieren.
In diesem Zusammenhang gibt es keine Empfehlung zur Verwendung von Puffergrößen. Die aktuellen und maximalen Größen der Systempools variieren von Klient zu Klient. Sie sollten jedoch wahrscheinlich nicht über 64k für jeden FileSystemWatcher / ReadDirectoryChangesW-Puffer gehen. Dies ergibt sich aus der Tatsache, dass es eine 64k-Beschränkung für den Netzwerkzugriff gibt, wie in ReadDirectoryChangesW dokumentiert. Aber am Ende müssen Sie die Anwendung auf einer Vielzahl von erwarteten Zielsystemen testen, damit Sie Ihren Puffer optimieren können.
Mit dieser Überlegung gibt es Overhead-Kosten im Zusammenhang mit .Net-Anwendungen und ich stelle mir vor, dass ein Win32-ReadDirectoryChangesW-Programm mit derselben Puffergröße möglicherweise bessere Leistung erzielen könnte. Bei sehr schnellen und zahlreichen Dateiänderungen sind Pufferüberläufe jedoch unvermeidlich und der Entwickler muss den Fall behandeln, wenn ein Überlauf auftritt, wie z.B. das manuelle Aufzählen des Verzeichnisses, um die Änderungen zu erkennen.
Zusammenfassend sind FileSystemWatcher und ReadDirectoryChangesW ein leichtgewichtiges Dateiänderungserkennungssystem, das seine Grenzen haben wird. Change Journals ist ein anderes System, das wir als mittelschwere Lösung betrachten würden, aber auch Einschränkungen haben:
http://msdn.microsoft.com/en-us/library/aa363798%28VS.85%29.aspx
Schwere Lösungen wären die Entwicklung eines dedizierten Dateisystemfiltertreibers, der im Dateisystemstack sitzt und Dateisystemänderungen überwacht. Natürlich wäre dies der komplexeste Ansatz. Die meisten Virenscanner, Backup-Software und Dateisystemüberwachungsdienstprogramme wie filemon (www.sysinternals.com) implementieren einen Filtertreiber.
Ich hoffe, die obige Erläuterung hilft Ihnen, die Ursache des Problems zu verstehen, das Sie erleben. Bitte antworten Sie, um uns mitzuteilen, ob Sie weitere Informationen benötigen. Danke.