Ich muss einen Windows-Dienst erstellen, der einen bestimmten Ordner auf neue Dateien hin überwacht und sie verarbeitet und an einen anderen Ort verschiebt.
Ich begann mit FileSystemWatcher
. Mein Chef mag FileSystemWatcher
nicht und möchte, dass ich den Abruf unter Verwendung von Timer
oder eines anderen Mechanismus als FileSystemWatcher
verwende.
Wie können Sie die Verzeichnisverwaltung überwachen, ohne FileSystemWatcher
mit .NET Framework zu verwenden?
Unter Verwendung von @ Petojs Antwort habe ich einen vollständigen Windows-Dienst hinzugefügt, der alle fünf Minuten nach neuen Dateien fragt. Es ist so eingeschränkt, dass nur ein Thread abfragt, die Verarbeitungszeit berücksichtigt und die Pause und das rechtzeitige Stoppen unterstützt. Es unterstützt auch das einfache Anhängen eines Debbuggers an system.start
%Vor%Tatsächlich ist die FileWatcher-Komponente aus meiner Erfahrung im Laufe der Jahre nicht zu 100% "stabil". Schieben Sie genügend Dateien in einen Ordner und Sie werden einige Ereignisse verlieren. Dies gilt insbesondere, wenn Sie eine Dateifreigabe überwachen, selbst wenn Sie die Puffergröße erhöhen.
Verwenden Sie FileWatcher also aus praktischen Gründen zusammen mit einem Timer, der einen Ordner nach Änderungen durchsucht, um die optimale Lösung zu finden.
Beispiele für die Erstellung von Timer-Code sollte reichlich vorhanden sein, wenn Sie es googlen. Wenn Sie beim Ausführen des Timers die letzte DateTime verfolgen, überprüfen Sie das Änderungsdatum jeder Datei und vergleichen Sie es mit dem Datum. Ziemlich einfache Logik.
Das Zeitgeberintervall hängt davon ab, wie dringend die Änderungen für Ihr System sind. Aber überprüfen Sie jede Minute sollte für viele Szenarien in Ordnung sein.
Verwenden Sie beim Programmstart Directory.GetFiles (Pfad), um die Liste der Dateien abzurufen.
Dann erstellen Sie einen Timer und in seinem abgelaufenen Ereignis Aufruf hasNewFiles:
%Vor%Im aufrufenden Code haben Sie neue Dateien, wenn:
%Vor%edit: wenn Sie eine linqy Lösung wollen:
%Vor%Ich würde fragen, warum nicht den FileSystemWatcher verwenden. Es registriert sich beim Betriebssystem und wird sofort benachrichtigt, wenn das Ereignis im Dateisystem beendet ist.
Wenn Sie wirklich abfragen müssen, erstellen Sie einfach einen System.Timers.Timer, erstellen Sie eine Methode zum Aufrufen und suchen Sie nach der Datei in dieser Methode.
Ja, Sie können einen Timer erstellen und einen Handler in das Elapsed-Ereignis einfügen, das eine DirectoryInfo-Klasse für das gerade angezeigte Verzeichnis instanziiert und entweder GetFiles () oder EnumerateFiles () aufruft. GetFiles () gibt ein FileInfo [] -Array zurück, während EnumerateFiles () ein "streaming" IEnumerable zurückgibt. EnumerateFiles () ist effizienter, wenn Sie erwarten, dass sich viele Dateien in diesem Ordner befinden, wenn Sie suchen. Sie können mit dem IEnumerable arbeiten, bevor die Methode alle FileInfos abgerufen hat, während GetFiles Sie warten lassen.
Warum dies möglicherweise besser als FileWatcher ist, hängt von der Architektur hinter den Kulissen ab. Nehmen wir zum Beispiel einen grundlegenden Workflow zum Extrahieren / Transformieren / Validieren / Laden. Erstens muss ein solcher Workflow möglicherweise teure Instanzen von Objekten erstellen (DB-Verbindungen, Instanzen einer Regel-Engine usw.). Dieser einmalige Overhead wird erheblich verringert, wenn der Workflow so strukturiert ist, dass alles, was ihm zur Verfügung steht, auf einmal bearbeitet werden kann. Zweitens würde FileWatcher erfordern, dass alles, was von den Ereignisprozeduren aufgerufen wird, wie dieser Workflow threadsicher ist, da viele Ereignisse gleichzeitig ausgeführt werden können, wenn Dateien ständig einfließen. Wenn dies nicht möglich ist, kann ein Timer sehr einfach konfiguriert werden um das System auf einen laufenden Workflow zu beschränken, indem Event-Handler ein thread-sicheres "Process Running" -Flag prüfen und einfach beenden, wenn ein anderes Handler-Thread es gesetzt und noch nicht beendet hat. Die Dateien in dem Ordner zu diesem Zeitpunkt werden bei der nächsten Ausführung des Timers aufgenommen, im Gegensatz zu FileWatcher. Wenn Sie den Handler beenden, geht die Information über das Vorhandensein dieser Datei verloren.
Es ist ein wenig merkwürdig, dass Sie FileSystemWatcher
oder vermutlich keine der Win32-APIs verwenden können, die das gleiche tun, aber das ist an dieser Stelle irrelevant. Die Abrufmethode könnte so aussehen.