Ответ 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) внедрить драйвер фильтра.
Я надеюсь, что приведенное выше объяснение поможет вам понять основную причину проблемы вы испытываете. Ответьте на сообщите нам, нужно ли вам дальнейшая информация. Спасибо.