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