Подтвердить что ты не робот

FileSystemWatcher и окна 7

Я пишу инструмент, который отслеживает сетевой каталог и запускается с машины Windows Server 2008, событие OnChanged для FileSystemWatcher запускается правильно из файлов, размещенных на сетевом диске, на любом компьютере, который не использует Windows 7, по какой-либо причине, если количество копируемых файлов больше 19 на компьютере с Windows 7 (сразу), то никакие события не запускаются, хотя они работают, если файлы выполняются индивидуально. Есть ли обходной путь для этого или это то, как ядро ​​Windows 7 ведет себя с событиями FSW?

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

4b9b3361

Ответ 1

От MSDN:

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

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

См. также этот связанный вопрос:

FileSystemWatcher работает неправильно, когда в файл одновременно добавлено много файлов...

Update:

Может возникнуть соблазн просто увеличить размер буфера, но это должно быть сделано с осторожностью. Фактически, существует ограничение на 64 КБ, когда дело доходит до доступа к сети. Класс FileSystemWatcher использует функцию Windows API ReadDirectoryChangesW, которая имеет этот предел:

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

Если вы хотите получить более глубокое понимание стоимости модификации размера буфера, вам следует взглянуть на пост Уолтера Ванга из Microsoft:

FileSystemWatcher по сети (полный пост, указанный ниже)

Извините, что документация FileSystemWatcher.InternalBufferSize не очень четко размер буфера при мониторинге сети дорожка. Рекомендуется не превышать 64 КБ при мониторинге сетевого пути.

FileSystemWatcher - это в основном .Net оболочка для Win32 API ReadDirectoryChangesW. Использовать ReadDirectoryChangesW, вы создаете и указать буфер, который ОС будет заполнить с изменениями. Однако, что не упоминается в Документация ReadDirectoryChangesW (но намекают на FileSystemWatcher docs) заключается в том, что файловая система создает внутреннее ядро буфер для сохранения информации об изменении временно, пока у него не будет возможности обновить пользовательский буфер. Размер созданный буфер ядра того же размера, который указан в ReadDirectoryChangesW и создан в незанятой объединенной памяти. Каждый раз файл FileSystemWatcher/ ReadDirectoryChangesW создается/ вызванный, новый буфер ядра также создан.

Пулы памяти ядра (paged и non-paged) отложены в системе адресное пространство для драйверов устройств и другие используемые компоненты ядра. Oни растут и сжимаются динамически, так как необходимо. Текущий размер бассейны можно легко увидеть, перейдя к вкладка "Производительность" Задачи Менеджер. Бассейны будут расти динамически, пока они не достигнут максимума значение, которое вычисляется во время загрузки и зависит от доступной системы ресурсов (в основном ОЗУ). Ты не хотите достичь этого максимального значения, иначе различные системные службы и драйверы начнет сбой. Однако это рассчитанное максимальное значение нелегко доступный. Чтобы определить максимальный размеры пула, вам нужно использовать ядро отладчик. Если вы заинтересованы в Дополнительная информация о системе пулов памяти, я рекомендую вам посмотрите главу 7 в книге MSPress Внутри Windows 2000 от Solomon и Russinovich.

Учитывая это, нет рекомендации относительно того, какие буферы размера вы можете использовать. Текущий и максимальный размер пулов системы будет варьироваться от клиента к клиенту. Однако вы, вероятно, не должны идти более 64 тыс. для каждого FileSystemWatcher/ ReadDirectoryChangesW буфер. Эта связано с тем, что существует Ограничение 64k с доступом к сети как задокументировано в ReadDirectoryChangesW. Но в конце концов вы будете иметь для тестирования приложения на разнообразном ожидаемых целевых систем, чтобы вы может настроить ваш буфер.

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

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

http://msdn.microsoft.com/en-us/library/aa363798%28VS.85%29.aspx

Тяжелые весовые решения написать выделенный фильтр файловой системы драйвер, который находится в файловой системе стек и контролирует файловую систему изменения. Конечно, это будет наиболее сложный подход. Большинство вирусов сканеры, программное обеспечение для резервного копирования и файл утилит системного мониторинга, таких как filemon (www.sysinternals.com) внедрить драйвер фильтра.

Я надеюсь, что приведенное выше объяснение поможет вам понять основную причину проблемы вы испытываете. Ответьте на сообщите нам, нужно ли вам дальнейшая информация. Спасибо.

Ответ 2

После многих попыток использования FileSystemWatcher я отказался от него. Он не будет корректно запускать события, в неподходящее время, неправильный тип. Честно говоря, я считаю это одним из худших классов в рамках .net. Я всегда заканчивал тем, что писал свой собственный класс, который принимает System.Timer, и по истечении x миллисекунд он проверяет каталоги, файлы вручную. Да, это требует больше работы, и да, это может быть небольшая PITA, но как только вы ее написали, вы можете использовать ее там, где хотите. Я хочу, чтобы FileSystemWatcher работал как рекламируемый, но я никогда не нашел его для этого.

Ответ 3

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

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

Ответ 4

Это один действительно ненадежный класс, когда файлы превышают определенный порог. У меня были события, которые запускались примерно 7 раз в исходной копии, а затем, когда диалог передачи файлов завершен, я получаю еще 7 событий, эта проблема возникает во всех OS'es, которые поддерживают FSW. Хотя Windows 7 (еще не пробовал vista еще) все еще принимает файлы по одному или 19 за раз, а если я удаляю файлы с компьютера XP в сетевой диск, я могу сразу читать тысячи файлов без каких-либо проблем. Это может быть просто изменение в ReadDirectoryChangesW с XP на 7. В прошлых 19 файлах я не мог получить ЛЮБЫЕ события для запуска, поэтому я думаю, что теперь это станет "функцией" моего инструмента. Если у кого-то есть какая-либо другая информация, не стесняйтесь вносить свой вклад.

Ответ 5

Если вы используете MacOSX + Parallels Desktop + Windows, Ваш код не работает, Из-за того, что ваше свойство FileSystemWatcher.Path является целевым для пути Mac, это UNC-путь, он не поддерживается!

введите описание изображения здесь