Система.ИО.FileSystemWatcher для мониторинга папки сетевого сервера-соображения производительности

Я хочу посмотреть на дерево папок на сетевом сервере для изменения. Все файлы имеют определенное расширение. В дереве есть около 200 папок и около 1200 файлов с расширением, которое я наблюдаю.

Я не могу написать сервис для запуска на сервере (off-limits!) так что решение должно быть локальным для клиента. Своевременность не имеет особого значения. Я могу жить с минутой или больше задержки в уведомлениях. Я наблюдаю за Create, Delete, Rename и Изменения.

будет использовать систему .NET.ИО.fileSystemWatcher создает большую нагрузку на сервер?

Как насчет 10 отдельных наблюдателей, чтобы сократить количество папок / файлов, наблюдаемых? (до 200 из 700 папок, 1200 из 5500 файлов в общей сложности) больше сетевого трафика вместо меньшего? Мои мысли-это перестановка на сервере, чтобы поместить наблюдаемые файлы под дерево 1. У меня не всегда есть этот вариант, поэтому команда наблюдателей.

Я полагаю, что другие решение-это периодическая проверка, создает ли FSW чрезмерную нагрузку на сервер или не работает по целому ряду причин типа SysAdmin.

есть ли лучший способ сделать это?

7 ответов


с точки зрения загрузки сервера, используя IO.FileSystemWatcher для удаленных уведомлений об изменениях в описываемом сценарии, вероятно,является наиболее эффективным методом. Он использует FindFirstChangeNotification и ReadDirectoryChangesW Win32 API функционирует внутренне, что, в свою очередь, взаимодействует с сетевым перенаправителем оптимизированным способом (при условии стандартной сети Windows: Если используется сторонний перенаправитель, и он не поддерживает необходимую функциональность, вещи не будут работать вообще). Оболочка .NET также использует асинхронный ввод-вывод и все остальное, обеспечивая максимальную эффективность.

единственная проблема с этим решением заключается в том, что оно не очень надежное. Кроме того, чтобы иметь дело с сетевыми подключениями, уходящими временно (что не слишком большая проблема, так как IO.FileSystemWatcher запустит событие ошибки в этом случае, которое вы можете обработать), базовый механизм имеет определенные фундаментальные ограничения. От Документация MSDN для функций Win32 API:

  • readdirectorychangesw завершается с ошибкой ERROR_INVALID_PARAMETER, когда длина буфера превышает 64 КБ и приложение отслеживает каталог по сети. Это связано с ограничением размера пакета с базовыми протоколами обмена файлами

  • уведомления не могут быть возвращены при вызове FindFirstChangeNotification для удаленного файла система

другими словами: при высокой нагрузке (когда вам понадобится большой буфер) или, что еще хуже, при случайных неопределенных обстоятельствах вы можете не получать уведомления, которые вы ожидаете. Это даже проблема с локальными наблюдателями файловой системы, но это гораздо больше проблемы по сети. еще один вопрос здесь на SO детализирует присущие проблемы надежности с API немного более подробно.

при использовании наблюдателей файловой системы ваш приложение должно быть в состоянии справиться с этими ограничениями. Например:

  • Если файлы, которые вы ищете, имеют порядковые номера, сохраните последний порядковый номер, о котором вы получили уведомление, чтобы вы могли искать "пробелы" в будущих уведомлениях и обрабатывать файлы, о которых вы не получили уведомления;

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

настройка нескольких слушателей-это то, чего вы должны избегать как можно больше: если что-нибудь, это сделает вещи даже меньше надежный...

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

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


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

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

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


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

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


на документация MSDN указывает что вы можете использовать компонент filesystemwatcher для отслеживания изменений файловой системы в сети диск.

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

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


Watcher выглядит на 100% надежным-просто посмотрите размер буфера на объекте watcher. Я протестировал тысячи обновлений файлов, ни один не потерян.

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


после использования системы.ИО.FileSystemWatcher на некоторое время. Он недостаточно стабилен для обработки событий, которые происходят слишком быстро. Чтобы обеспечить 100% чтение файлов. Я использую простые методы каталогов для поиска по файлам. После прочтения немедленно скопируйте файлы в другую папку. Чтобы изолировать его от новых файлов, добавляемых во время чтения файлов.

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

var fileNames = каталог.GetFiles (srcFolder); foreach (строковое имя файла в именах файлов) { string [] lines = файл.ReadAllLines (имя файла);


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

можно было бы предположить, что сообщение или событие только поднял / отправил в сетевой FSW, когда происходит изменение.

но это все только предположения. :)