События FileSystemWatcher повышаются дважды, несмотря на принятие мер против него

Я просмотрел довольно много потоков здесь и на других сайтах для решения этой проблемы.

Здесь мой класс FileMonitor:

class FileMonitor
{
    public FileMonitor(String path)
    {
        try
        {
            var watcher = new FileSystemWatcher()
            {
                Path = path,
                IncludeSubdirectories = true,
                InternalBufferSize = 65536,
                EnableRaisingEvents = true
            };

            watcher.Changed += new FileSystemEventHandler(OnFileChanged);
            watcher.Created += new FileSystemEventHandler(OnFileCreated);
            watcher.Deleted += new FileSystemEventHandler(OnFileDeleted);
            watcher.Renamed += new RenamedEventHandler(OnFileRenamed);
            watcher.Error += new ErrorEventHandler(OnWatcherError);
        }
        catch (Exception)
        {

            throw;
        }
    }

    private void OnWatcherError(object sender, ErrorEventArgs e)
    {

    }

    private void OnFileChanged(object sender, FileSystemEventArgs e)
    {
        try
        {
            ((FileSystemWatcher)sender).EnableRaisingEvents = false;

            LogFileSystemChanges(e);
        }

        finally
        {
            ((FileSystemWatcher)sender).EnableRaisingEvents = true;
        }
    }

    private void OnFileCreated(object sender, FileSystemEventArgs e)
    {
        try
        {
            ((FileSystemWatcher)sender).EnableRaisingEvents = false;

            LogFileSystemChanges(e);
        }

        finally
        {
            ((FileSystemWatcher)sender).EnableRaisingEvents = true;
        }
    }

    private void OnFileDeleted(object sender, FileSystemEventArgs e)
    {
        try
        {
            ((FileSystemWatcher)sender).EnableRaisingEvents = false;

            LogFileSystemChanges(e);
        }

        finally
        {
            ((FileSystemWatcher)sender).EnableRaisingEvents = true;
        }
    }

    private void OnFileRenamed(object sender, RenamedEventArgs e)
    {
        try
        {
            ((FileSystemWatcher)sender).EnableRaisingEvents = false;

            LogFileSystemRenaming(e);
        }

        finally
        {
            ((FileSystemWatcher)sender).EnableRaisingEvents = true;
        }
    }

    private void LogFileSystemChanges(FileSystemEventArgs e)
    {
        string log = string.Format("{0:G}: {1} | {2}", DateTime.Now, e.FullPath, e.ChangeType);
        Console.WriteLine(log);
    }

    private void LogFileSystemRenaming(RenamedEventArgs e)
    {
        string log = string.Format("{0:G}: {1} | Old name: {2}", DateTime.Now, e.FullPath, e.OldName);
        Console.WriteLine(log);
    }
}

Как вы можете сказать, я попробовал "блокировку" ((FileSystemWatcher)sender).EnableRaisingEvents = false;, но могу сказать, что с моего вывода на консоль мои события запускаются дважды.

Есть идеи по этому поводу? Я действительно не уверен, куда идти отсюда.

Ответ 1

У меня была такая же проблема, и после того, как много шума вышло к выводу, что Блокнот пишет файл три раза (!) в строке. Если приложение действительно сохраняет это часто (возможно, для триангуляции резервных копий и т.д.), Вы не можете многое сделать.

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

Ответ 2

Я пытался использовать класс FileSystemWatcher раньше (много лет назад он оказался - 2008) и имел серьезные проблемы. Это нечеткая абстракция в лучшем случае. Я сообщил о своих выводах в то время CodeProject. Ищите "Glytzhkof" в списке комментариев. Насколько я помню, у меня были проблемы практически со всеми аспектами класса, но он мог быть улучшен уже через несколько лет.

В целом, мой опыт в тот день состоял в том, что события полностью исчезли или свалились, вызывая исключения на основе таких переменных, как доступ к кешу записи на диск, будь то доступ к RAID, NAS или обычным дискам и другие случайные аппаратные проблемы, Я точно не помню. Интересно, что, похоже, он работал с путями UNC. Не знаю, почему. Сбой подключенных дисков.

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

ОБНОВЛЕНИЕ: см. новую информацию здесь: fooobar.com/info/45353/...