Страницы

Поиск по вопросам

понедельник, 8 октября 2018 г.

Как решить повтор события change в FileSystemWatcher?

Мониторинг файла. При изменениях в файле почему-то дважды запускается 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; } }
Если файл изменяется не очень часто, а события приходят одно за другим, то можно использовать таймер с некоторым ожиданием и отсекать события, для которых не прошло нужное количество времени.
В общем, выбор решения целиков зависит от ваших требований (впрочем, как обычно :)).

Комментариев нет:

Отправить комментарий