FileSystemWatcher против опроса для просмотра изменений файла

Мне нужно настроить приложение, которое следит за созданием файлов в каталоге, как локально, так и на сетевом диске.

Лучшим вариантом будет FileSystemWatcher или опрос по таймеру. Я использовал оба метода в прошлом, но не широко.

Какие проблемы (производительность, надежность и т.д.) существуют с любым методом?

Ответ 1

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

Изменить: если у вас есть пользовательский интерфейс, вы также можете дать своему пользователю возможность "обновлять" для изменений вместо опроса. Я бы объединил это с наблюдателем файловой системы.

Ответ 2

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

Вот статья MSDN в буфере: FileSystemWatcher..::. Свойство InternalBufferSize

В MSDN:

Увеличение размера буфера является дорогостоящим, поскольку оно исходит из неопытной памяти, которая не может быть заменена на диск, поэтому держите буфер как можно меньше. Чтобы избежать переполнения буфера, используйте свойства NotifyFilter и IncludeSubdirectories для фильтрации нежелательных уведомлений об изменениях.

Мы используем 16 МБ из-за ожидаемой большой партии. Работает отлично и никогда не пропускает файл.

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

Для проблем с блокировкой файлов я создаю процесс, который ждет, когда файл будет разблокирован, ожидая одну секунду, затем два, затем четыре и т.д. Опрос никогда. Это происходило без ошибок в течение примерно двух лет.

Ответ 3

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

Как уже упоминалось в @ChillTemp выше, наблюдатель может не работать с не-Windows файлами. Например, он не будет работать вообще на установленных накопителях Novell.

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

Ответ 4

Также обратите внимание, что наблюдатель файловой системы не является надежным в общих папках файлов. В частности, если общий ресурс файла размещен на сервере, отличном от Windows. FSW не следует использовать для чего-либо критического. Или следует использовать со случайным опросом, чтобы убедиться, что он ничего не пропустил.

Ответ 5

Лично я использовал FileSystemWatcher в производственной системе, и он отлично работал. За последние 6 месяцев у него не было ни одного икоты, работающей 24x7. Он контролирует одну локальную папку (которая является общей). У нас относительно небольшое количество файловых операций, которые он должен обрабатывать (10 событий, выпущенных в день). Мне не о чем беспокоиться. Я бы использовал его снова, если мне пришлось переделать решение.

Ответ 6

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

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

У меня нет опыта работы с файлами для удаленного просмотра файлов и не Windows.

Я бы подумал о том, чтобы опрос файла был лишним и не стоил накладных расходов, если вы по своей сути не доверяете FileSystemWatcher или непосредственно испытывали ограничения, перечисленные всеми остальными здесь (не общие для Windows и удаленное просмотр файлов).

Ответ 7

У меня возникли проблемы с использованием FileSystemWatcher в сетевых ресурсах. Если вы находитесь в чистой среде Windows, это может быть не проблема, но я смотрел общий ресурс NFS и, поскольку NFS не имеет статуса, никогда не было уведомлений, когда файл, который я смотрел, изменился.

Ответ 8

Я бы пошел с опросом.

Проблемы с сетью приводят к ненадежности FileSystemWatcher (даже при перегрузке события ошибки).

Ответ 9

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

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

Кроме того, у меня вообще не было проблем с локальными папками, независимо от того, были они разделены или нет.

Ответ 10

Использование FSW и опроса - пустая трата времени и ресурсов, на мой взгляд, и я удивлен, что опытные разработчики предлагают это. Если вам нужно использовать опрос для проверки "промахов FSW", вы можете, естественно, полностью отказаться от FSW и использовать только опрос.

В настоящее время я пытаюсь решить, буду ли я использовать FSW или опрос для проекта, который я разрабатываю. Читая ответы, очевидно, что есть случаи, когда FSW полностью удовлетворяет потребности, а в других случаях вам нужен опрос. К сожалению, ни один ответ на самом деле не касался разницы в производительности (если таковой имеется), только с проблемами "надежности". Есть ли кто-нибудь, кто может ответить на эту часть вопроса?

EDIT: nmclean указывает на правильность использования как FSW, так и опроса (вы можете прочитать обсуждение в комментариях, если вы заинтересованы) представляется очень рациональным объяснением, почему могут быть ситуации что использование как FSW, так и опроса является эффективным. Спасибо, что пролили свет на это для меня (и у кого-то другого было такое же мнение), nmclean.

Ответ 11

Рабочее решение для работы с событием create вместо изменения

Даже для копирования, вырезания, вставки, перемещения.

class Program
{        

        static void Main(string[] args)
        {
            string SourceFolderPath = "D:\\SourcePath";
            string DestinationFolderPath = "D:\\DestinationPath";
            FileSystemWatcher FileSystemWatcher = new FileSystemWatcher();
            FileSystemWatcher.Path = SourceFolderPath;
            FileSystemWatcher.IncludeSubdirectories = false;
            FileSystemWatcher.NotifyFilter = NotifyFilters.FileName;   // ON FILE NAME FILTER       
            FileSystemWatcher.Filter = "*.txt";         
             FileSystemWatcher.Created +=FileSystemWatcher_Created; // TRIGGERED ONLY FOR FILE GOT CREATED  BY COPY, CUT PASTE, MOVE  
            FileSystemWatcher.EnableRaisingEvents = true;

            Console.Read();
        }     

        static void FileSystemWatcher_Created(object sender, FileSystemEventArgs e)
        {           
                string SourceFolderPath = "D:\\SourcePath";
                string DestinationFolderPath = "D:\\DestinationPath";

                try
                {
                    // DO SOMETING LIKE MOVE, COPY, ETC
                    File.Copy(e.FullPath, DestinationFolderPath + @"\" + e.Name);
                }
                catch
                {
                }          
        }
}

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

class Program
{
    static string IsSameFile = string.Empty;  // USE STATIC FOR TRACKING

    static void Main(string[] args)
    {
         string SourceFolderPath = "D:\\SourcePath";
        string DestinationFolderPath = "D:\\DestinationPath";
        FileSystemWatcher FileSystemWatcher = new FileSystemWatcher();
        FileSystemWatcher.Path = SourceFolderPath;
        FileSystemWatcher.IncludeSubdirectories = false;
        FileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite;          
        FileSystemWatcher.Filter = "*.txt";         
        FileSystemWatcher.Changed += FileSystemWatcher_Changed;
        FileSystemWatcher.EnableRaisingEvents = true;

        Console.Read();
    }     

    static void FileSystemWatcher_Changed(object sender, FileSystemEventArgs e)
    {
        if (e.Name == IsSameFile)  //SKIPS ON MULTIPLE TRIGGERS
        {
            return;
        }
        else
        {
            string SourceFolderPath = "D:\\SourcePath";
            string DestinationFolderPath = "D:\\DestinationPath";

            try
            {
                // DO SOMETING LIKE MOVE, COPY, ETC
                File.Copy(e.FullPath, DestinationFolderPath + @"\" + e.Name);
            }
            catch
            {
            }
        }
        IsSameFile = e.Name;
    }
}

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

Ответ 12

Я бы сказал, что использовать опрос, особенно в TDD-сценарии, так как гораздо проще обмануть/заглушить присутствие файлов или иначе, когда событие опроса запущено, чем полагаться на более "неконтролируемое" событие fsw. + к тому, что работали над множеством приложений, которые страдали от ошибок fsw.