FileSystemWatcher получает слишком много событий - PullRequest
0 голосов
/ 22 февраля 2012

Я пытаюсь реализовать средство просмотра файлов, которое будет вызывать событие, если содержимое файла было изменено.Проблема в том, что после изменения файла, который я смотрю, я получаю 2 события.(Я хочу получить его только один раз)

_automationStatusWatcher = new FileSystemWatcher(fileInfo.Directory.FullName,
                                                 fileInfo.Name);
_automationStatusWatcher.NotifyFilter = NotifyFilters.LastWrite;
_automationStatusWatcher.Changed += OnAutomationStatusChanged;
_automationStatusWatcher.EnableRaisingEvents = true;

Файл, который я смотрю, не предназначен для воссоздания / перемещения / удаления / чего бы то ни было.его цель - быть файлом базы данных xml, который мне нужен для мониторинга, как только он изменится.я хочу получить только 1 событие при изменении файла и игнорировать другие события.

Как я могу это сделать?

Ответы [ 6 ]

2 голосов
/ 22 февраля 2012

Я должен был справиться с этой проблемой некоторое время назад. Я хотел получать уведомления, когда файл был создан. Проблема заключалась в том, что событие вызывается, когда файл все еще пустой или все еще записывается, а не когда новый файл закрыт.

Решением было создание файла с использованием временного имени и по окончании переименование файла в его окончательное имя. Затем я наблюдал за событием переименования.

Вы можете присвоить файлу имя myfile.tmp во время записи в него, а когда закончите, переименовать его в myfile.xml и посмотреть событие переименования.

2 голосов
/ 22 февраля 2012

Руководство

Примечание

Обычные операции файловой системы могут вызывать более одного события. Например, когда файл перемещается из одного каталога в другой, могут возникнуть несколько событий OnChanged и некоторые события OnCreated и OnDeleted. Перемещение файла - это сложная операция, которая состоит из нескольких простых операций, поэтому вызывает несколько событий. Аналогично, некоторые приложения (например, антивирусное программное обеспечение) могут вызывать дополнительные события файловой системы, которые обнаруживаются FileSystemWatcher.

1 голос
/ 27 декабря 2013

Я тоже столкнулся с этой проблемой, теперь я узнал так:

new Thread(() => {
            while (true) {
                var r = watch.WaitForChanged(WatcherChangeTypes.All);
                this.Invoke(new ThreadStart(() => {
                    listBox1.Items.Add(string.Format("{0} {1} {2}", DateTime.Now, r.Name, r.ChangeType));
                }));
            }
        }) { IsBackground = true }.Start();

очень похоже на nio в Java

1 голос
/ 22 февраля 2012

Вы можете попытаться отсоединить ваш обработчик событий, как только вы поймете изменение, пока не будете готовы принять больше изменений:

_automationStatusWatcher.Changed -= OnAutomationStatusChanged;

Но это не обязательно потокобезопасно, и вы все равно можете получить многократные выстрелы. Другой вариант - использовать переменную семафора, чтобы узнать, обрабатываете ли вы это изменение:

private bool _inStatusChange = false;
private void OnAutomationStatusChanged(object sender, args...)
{
    if (_inStatusChange)
    {
        return;
    }
    else
    {
         _inStatusChange = true;
        //do work
        _inStatusChange = false;

    }
}

Вы должны использовать соответствующую блокировку, чтобы обеспечить безопасный доступ к переменной потока семафора.

0 голосов
/ 22 февраля 2012

У меня была похожая проблема при проверке обновлений в конфигурациях журналов.
Я читал о проблеме множественных событий FileSystemWatcher. Поэтому я решил реализовать другое решение.

Я проверяю каждый доступ к моему файлу конфигурации, если он изменился, сравнивая дату изменения. Позже я добавил задержку (2 секунды), чтобы избежать слишком большого доступа к файловой системе. Может быть, вы также можете использовать этот способ.

0 голосов
/ 22 февраля 2012

Если вы посмотрите на документацию для FileSystemWatcher , там написано, что она сработает несколько раз.

Moving a file is a complex operation that consists of multiple simple operations, therefore raising multiple events. Likewise, some applications (for example, antivirus software) might cause additional file system events that are detected by FileSystemWatcher.

Я бы порекомендовал использовать какой-нибудь механизм организации очередей, чтобы у вас не было нескольких действий над одним файлом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...