FileSystemWatcher против опроса, чтобы наблюдать за изменениями файла - PullRequest
141 голосов
/ 27 октября 2008

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

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

Какие проблемы (производительность, надежность и т. Д.) Возникают при использовании любого из этих методов?

Ответы [ 13 ]

105 голосов
/ 27 октября 2008

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

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

60 голосов
/ 05 июня 2009

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

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

За MSDN:

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

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

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

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

34 голосов
/ 27 октября 2008

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

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

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

17 голосов
/ 27 октября 2008

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

11 голосов
/ 27 октября 2008

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

7 голосов
/ 27 октября 2008

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

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

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

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

5 голосов
/ 27 октября 2008

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

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

5 голосов
/ 27 октября 2008

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

3 голосов
/ 27 октября 2008

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

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

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

2 голосов
/ 10 августа 2018

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

private void Watcher_Created(object sender, FileSystemEventArgs e)
{
    Task.Run(() => MySubmit(e.FullPath));
}
...