2013-02-22 25 views
59

Ich verwende eine Windows Forms-Anwendung, um ein Verzeichnis zu überwachen und die darin enthaltenen Dateien in ein anderes Verzeichnis zu verschieben.Verwenden von FileSystemWatcher zum Überwachen eines Verzeichnisses

Im Moment wird es die Datei in ein anderes Verzeichnis kopieren, aber wenn eine andere Datei hinzugefügt wird, wird es einfach mit keiner Fehlermeldung enden. Manchmal kopiert es zwei Dateien, bevor es auf der dritten endet.

Liegt das daran, dass ich eine Windows Form-Anwendung anstelle einer Konsolen-App verwende? Gibt es eine Möglichkeit, das Beenden des Programms zu stoppen und das Verzeichnis weiter zu verfolgen?

private void watch() 
{ 
    FileSystemWatcher watcher = new FileSystemWatcher(); 
    watcher.Path = path; 
    watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite 
         | NotifyFilters.FileName | NotifyFilters.DirectoryName; 
    watcher.Filter = "*.*"; 
    watcher.Changed += new FileSystemEventHandler(OnChanged); 
    watcher.EnableRaisingEvents = true; 
} 

private void OnChanged(object source, FileSystemEventArgs e) 
{ 
    //Copies file to another directory. 
} 

Antwort

85

Das Problem war die Benachrichtigung Filter. Das Programm hat versucht, eine Datei zu öffnen, die noch kopiert wurde. Ich habe alle Benachrichtigungsfilter mit Ausnahme von LastWrite entfernt.

private void watch() 
{ 
    FileSystemWatcher watcher = new FileSystemWatcher(); 
    watcher.Path = path; 
    watcher.NotifyFilter = NotifyFilters.LastWrite; 
    watcher.Filter = "*.*"; 
    watcher.Changed += new FileSystemEventHandler(OnChanged); 
    watcher.EnableRaisingEvents = true; 
} 
20

Sie haben liefern nicht die Datei Code verarbeitet, aber ich nehme an, Sie machte den gleichen Fehler macht jeder, wenn zuerst so etwas zu schreiben: das Penguin Computing Event wird so schnell angehoben werden, wenn die Datei erstellt wird. Es wird jedoch einige Zeit dauern, bis die Datei fertig ist. Nehmen Sie eine Dateigröße von beispielsweise 1 GB. Die Datei kann von einem anderen Programm erstellt werden (Explorer.exe kopiert es von irgendwo), aber es dauert einige Minuten, bis dieser Prozess abgeschlossen ist. Das Ereignis wird zum Zeitpunkt der Erstellung ausgelöst und Sie müssen warten, bis die Datei zum Kopieren bereit ist.

Sie können warten, bis eine Datei bereit ist, indem Sie die Funktion this in einer Schleife verwenden.

14

Der Grund kann sein, dass Watcher als lokale Variable für eine Methode deklariert ist und nach Abschluss der Methode Garbage gesammelt wird. Sie sollten es als Klassenmitglied deklarieren. Versuchen Sie Folgendes:

FileSystemWatcher watcher; 

private void watch() 
{ 
    watcher = new FileSystemWatcher(); 
    watcher.Path = path; 
    watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite 
         | NotifyFilters.FileName | NotifyFilters.DirectoryName; 
    watcher.Filter = "*.*"; 
    watcher.Changed += new FileSystemEventHandler(OnChanged); 
    watcher.EnableRaisingEvents = true; 
} 

private void OnChanged(object source, FileSystemEventArgs e) 
{ 
    //Copies file to another directory. 
} 
+9

'Watcher' Variable wird am Leben gehalten (nicht Müll gesammelt), weil er Changed Event abonniert hat. – adospace

Verwandte Themen