Я хочу наблюдать за изменениями в дереве папок на сетевом сервере. Все файлы имеют определенное расширение. В дереве около 200 папок и около 1200 файлов с расширением, которое я просматриваю.
Я не могу написать службу для запуска на сервере (запрещено!), Поэтому решение должно быть локальным для клиента. Своевременность не особо важна. Я могу жить с задержкой в минуту или больше. Я слежу за созданием, удалением, переименованием и изменениями.
Будет ли использование .NET System.IO.fileSystemWatcher большой нагрузкой на сервер?
Как насчет 10 отдельных наблюдателей, чтобы сократить количество просматриваемых папок / файлов? (до 200 из 700 папок, 1200 из 5500 файлов) Больше сетевого трафика вместо меньшего? Мои мысли - это перестановка на сервере, чтобы наблюдаемые файлы поместить под 1 дерево. У меня не всегда есть этот вариант, поэтому команда наблюдателей.
Я полагаю, что другое решение - это периодическая проверка, создает ли FSW чрезмерную нагрузку на сервер или не работает по целому ряду причин типа SysAdmin.
Есть лучший способ сделать это?





Я бы не подумал, что существует какое-либо активное состояние или связь между компьютером с FSW и компьютером, местоположение которого отслеживается. Другими словами, FSW не отправляет эхо-запрос сетевой ОС для проверки файла.
Можно представить, что сообщение или событие Только генерируется / отправляется в сетевой FSW, когда происходит изменение.
Но это все лишь домыслы. :)
У нас есть ответ, но отвечу на ваш вопрос: FSW отправит запрос на компьютер, чтобы получать уведомление при изменении файла. Вы не постоянно спрашиваете журнал, есть ли у него новый выпуск, вы подписываетесь один раз, и они рассылают новые выпуски, когда они публикуются.
Документация MSDN указывает, который можно использовать с помощью компонента FileSystemWatcher для отслеживания изменений файловой системы в сети водить машину.
Это также указывает на то, что компонент-наблюдатель прослушивает уведомления об изменении файловой системы, а не периодически опрашивает целевой диск на предмет изменений.
Исходя из этого, объем сетевого трафика полностью зависит от того, насколько вы ожидаете изменения содержимого этого сетевого диска. Компонент FSW не увеличивает уровень сетевого трафика.
С точки зрения загрузки сервера использование IO.FileSystemWatcher для удаленных уведомлений об изменениях в описанном вами сценарии, вероятно, является наиболее эффективным из возможных методов. Он использует внутренние функции Win32 API FindFirstChangeNotification и ReadDirectoryChangesW, которые, в свою очередь, обмениваются данными с сетевым перенаправителем оптимизированным образом (при условии стандартной сети Windows: если используется сторонний перенаправитель и он не поддерживает требуемые функции, все выиграно. вообще не работает). Оболочка .NET также использует асинхронный ввод-вывод и все остальное, что дополнительно обеспечивает максимальную эффективность.
Единственная проблема с этим решением в том, что оно не очень надежное. Помимо необходимости иметь дело с временным отключением сетевых подключений (что не является большой проблемой, поскольку IO.FileSystemWatcher в этом случае вызовет событие ошибки, с которым вы можете справиться), базовый механизм имеет определенные фундаментальные ограничения. Из документации MSDN для функций Win32 API:
ReadDirectoryChangesW завершается ошибкой с ERROR_INVALID_PARAMETER, когда длина буфера превышает 64 КБ, а приложение отслеживает каталог по сети. Это связано с ограничением размера пакета с базовыми протоколами обмена файлами.
Уведомления могут не возвращаться при вызове FindFirstChangeNotification для удаленной файловой системы
Другими словами: при высокой нагрузке (когда вам понадобится большой буфер) или, что еще хуже, при случайных неуказанных обстоятельствах вы можете не получать ожидаемые уведомления. Это проблема даже для локальных наблюдателей файловой системы, но это гораздо большая проблема в сети. Еще один вопрос здесь, на SO более подробно описывает проблемы надежности, присущие API.
При использовании наблюдателей файловой системы ваше приложение должно уметь справляться с этими ограничениями. Например:
Если файлы, которые вы ищете, имеют порядковые номера, сохраните последний порядковый номер, о котором вы получили уведомление, чтобы вы могли искать «пробелы» в будущих уведомлениях и обрабатывать файлы, о которых вы не получали уведомления;
При получении уведомления всегда выполняйте полное сканирование каталога. Это может показаться очень плохим, но, поскольку сканирование управляется событиями, оно по-прежнему намного эффективнее, чем тупой опрос. Кроме того, пока вы сохраняете общее количество файлов в одном каталоге, а также количество каталогов для сканирования, меньше тысячи или около того, влияние этой операции на производительность в любом случае должно быть минимальным.
Настройка нескольких слушателей - это то, чего вы должны избегать как можно больше: во всяком случае, это сделает даже меньше надежным ...
В любом случае, если вы абсолютно имеют для использования наблюдателей файловой системы, все может работать нормально, если вы знаете об ограничениях, и не ожидайте уведомления 1: 1 для каждого измененного / созданного файла.
Итак, если у вас есть другие варианты (по сути, процесс записи файлов уведомляет вас не на основе файловой системы: любой обычный метод RPC будет улучшением ...), на них определенно стоит обратить внимание с точки зрения надежности зрения.
Я использовал наблюдатели файловой системы из C# несколько раз. В первый раз, когда я их использовал, у меня были проблемы с их прекращением работы, в основном из-за того, что я обрабатывал изменения в потоке, сообщившем об изменении.
Однако теперь я просто помещаю изменение в очередь и обрабатываю ее в другом потоке. Похоже, это решило мою изначальную проблему. Для вашей проблемы у вас может быть несколько наблюдателей, нажимающих на одну и ту же очередь.
Однако я не использовал это с вашим масштабом проблемы.
По моему опыту, FSW не создает большого сетевого трафика. Однако, если есть проблема с производительностью, ваш подход с использованием нескольких наблюдателей и разбиением их на меньшее количество просматриваемых папок кажется разумным.
Однако у меня были большие проблемы с FSW на сетевых дисках: удаление файла всегда вызывало событие ошибки, а не событие удаления. Я не нашел решения, поэтому теперь избегаю использования FSW, если есть способ обойти это ...
Watcher выглядит на 100% надежным - просто посмотрите размер буфера объекта-наблюдателя. Я протестировал тысячи файлов-обновлений, ни одно не потеряно.
Я рекомендую использовать многопоточный подход - триггер является наблюдателем за файлами. Он может запускать поток для каждого обнаруженного изменения файла. Наблюдатель может обрабатывать намного быстрее с меньшей вероятностью переполнения. (используйте поток Async)
Он может выглядеть на 100% надежным в локальной файловой системе, но ужасно ненадежен в общей сетевой папке. Если файловый сервер, обслуживающий общий ресурс, не работает, мозг FSW мертв.
Чтобы добавить к тому, что сказал DSoa, я прямо сейчас испытываю эту проблему. Сетевые ресурсы НЕ будут вызывать событие ошибки в FileShareWatcher, если путь UNC отключен. Еще раз, когда UNC-путь повторно подключается, никакие события для FSW больше не срабатывают!
После использования System.IO.FileSystemWatcher какое-то время. Он недостаточно стабилен, чтобы обрабатывать слишком быстрые события. Чтобы обеспечить 100% чтение файлов. Я использую простые методы каталогов для поиска файлов. Прочитав его, сразу скопируйте файлы в другую папку. Чтобы изолировать его от новых файлов, добавляемых во время чтения файлов.
Таймер используется для регулярного чтения папки. Копируя уже прочитанный файл в папку архива, убедитесь, что он больше не будет прочитан. При последующем чтении всегда будут новые файлы.
var fileNames = Directory.GetFiles(srcFolder);
foreach (string fileName in fileNames)
{
string[] lines = File.ReadAllLines(fileName);
}
Как клиент узнает, что на сервере что-то изменилось, если он не пингует это? AFAIK FSW не запускает никаких процессов на сервере. Тем не менее, AFIK в этом случае немного.