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

StackOverflow https://stackoverflow.com/questions/151804

Вопрос

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

Я не могу написать службу для запуска на сервере (запрещено!), Поэтому решение должно быть локальным для клиента.Своевременность не особенно важна.Я могу смириться с минутной или более задержкой в уведомлениях.Я наблюдаю за Созданием, Удалением, Переименованием и изменениями.

Будет ли использование .NET System.IO.FileSystemWatcher создавать большую нагрузку на сервер?

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

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

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

Это было полезно?

Решение

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

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

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

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

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

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

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

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

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

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

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

Другие советы

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

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

Тем не менее, я не использовал это при вашем масштабе проблемы.

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

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

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

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

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

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

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

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

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

var fileNames = Directory.GetFiles(srcFolder);
foreach (string fileName in fileNames)
{
   string[] lines = File.ReadAllLines(fileName);
}

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top