Как решить повтор события change в FileSystemWatcher?
1,00
р.
р.
Мониторинг файла. При изменениях в файле почему-то дважды запускается Change. Как можно это решить? Вот код: public void monitoring(string path) { this.sPath = path string first = Path.GetDirectoryName(path) string second = Path.GetFileName(path) FileSystemWatcher fsw = new FileSystemWatcher(first, second) fsw.Changed += new FileSystemEventHandler(watcher_Changed) fsw.EnableRaisingEvents = true } public void watcher_Changed(object sender, FileSystemEventArgs e) { MessageBox.Show("Be happy :3") SplitAndQuery(this.sPath) }
Ответ Дело в том, что FileSystemWatcher опирается на уведомления от ОС. А запись изменений в файл далеко не всегда может являться атомарным действием: например, notepad.exe пишет на диск в несколько приемов, отдельно файл и отдельно его атрибуты, что повлечет за собой несколько срабатываний события Changed. Или при копировании/перемещении файлов запись происходит в несколько приемов. Избавиться от этого можно попробовать разными способами. Самый железобетонный, но не всегда подходящий -- отключать генерацию событий. Но пользоваться им надо аккуратно, т.к. можно пропустить другие полезные изменения. public void watcher_Changed(object sender, FileSystemEventArgs e) { watcher.EnableRaisingEvents = false try { MessageBox.Show("Be happy :3") SplitAndQuery(this.sPath) } finally { watcher.EnableRaisingEvents = true } } Другой подход -- опираться на дату последней модификации файла (опционально еще и на e.ChangeType): DateTime lastWriteTime = DateTime.MinValue public void watcher_Changed(object sender, FileSystemEventArgs e) { DateTime writeTime = File.GetLastWriteTime(this.sPath) if (lastWriteTime != writeTime) { MessageBox.Show("Be happy :3") SplitAndQuery(this.sPath) lastWriteTime = writeTime } } Если файл изменяется не очень часто, а события приходят одно за другим, то можно использовать таймер с некоторым ожиданием и отсекать события, для которых не прошло нужное количество времени. В общем, выбор решения целиков зависит от ваших требований (впрочем, как обычно :)).