c# FileSystemWatcher срабатывает дважды при прослушивании OnChanged


Пытается реализовать FileSystemWatcher, но функция OnChanged вызывается дважды при сохранении файла. основываясь на некоторых других сообщениях, я подозреваю, что фильтр LastWrite имеет несколько событий? Я думал, что NotifyFilters ограничит его только запуском при записи файла, но что-то другое заставляет функцию работать дважды. e.ChangeType только говорит мне, что файл изменился, но не точно, как. Есть ли способ ограничить это бегом только один раз?

    public MainWindow()
    {
        InitializeComponent();

        FileSystemWatcher fsw = new FileSystemWatcher(path);
        fsw.NotifyFilter = NotifyFilters.LastWrite;
        fsw.EnableRaisingEvents = true;
        fsw.Changed += new FileSystemEventHandler(OnChanged);
    }

    private void OnChanged(object sender, FileSystemEventArgs e)
    {
        if (newString == null)
        {
            using (StreamReader sr = new StreamReader(new FileStream(e.FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
            {
                lastString = sr.ReadToEnd();
            }
            difference = lastString;
        } else {
            using (StreamReader sr = new StreamReader(new FileStream(e.FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
            {
                newString = sr.ReadToEnd();
            }
            int newCount = newString.Count();
            int count = lastString.Count();
            // MessageBox.Show("last:" + lastString.Count().ToString(), "next: " + newString.Count());
            difference = newString.Remove(0,5);
            lastString = newString;
        }
        Application.Current.Dispatcher.Invoke(new Action(() => { tb_content.Text = difference; }));
        MessageBox.Show(e.ChangeType.ToString(), "");
    }
}
2 2

2 ответа:

Вы можете отфильтровать его сами, как я написал здесь.

Альтернатива ответу Фредерика:

Небольшой обходной путь, который приходит на ум, состоит в том, чтобы предотвратить выполнение метода OnChanged, если он уже выполняется.

Например:

private bool IsExecuting { get; set; }

private void OnChanged(object sender, FileSystemEventArgs e)
{
    if (!IsExecuting) 
    {
        IsExecuting = true;

        // rest of your code

        IsExecuting = false;
    }
}