Как уберечь ReadDirectoryChangesW от пропущенных изменений файла

В Интернете есть много сообщений о том, что функция API ReadDirectoryChangesW пропускает файлы при большой активности файлов. Большинство винят скорость, с которой вызывается цикл функции ReadDirectoryChangesW. Это неверное предположение. Лучшее объяснение, которое я видел, находится в следующем сообщении, комментарии от понедельника, 14 апреля 2008 г., 14:15:27.

http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/4465cafb-f4ed-434f-89d8-c85ced6ffaa8/

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

Вопрос в том, нашел ли кто-нибудь надежный способ использовать функцию ReadDirectoryChangesW без необходимости каждый раз сбрасывать том? Это недопустимо, если пользователь не является администратором, и для завершения может потребоваться некоторое время.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
21
0
6 604
3

Ответы 3

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

Поэтому, если вы отслеживаете последние 50-100 раз, когда произошло событие ReadDirectoryChangesW/ FSW, и видите, что оно вызывается быстро, вы можете обнаружить это и запустить специальное условие, чтобы получить все файлы, которые были изменены (и установить флаг для временного предотвращения будущих ложных событий FSW) за несколько секунд.

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

Это будет работать примерно 99% времени. Что произойдет, если будет пропущен файл в другом каталоге (кроме того, в котором много изменений файла). Вы просканируете один каталог на предмет изменений, но пропустите изменение одного файла в другом.

SpecialK 12.09.2008 18:17

Класс FileSystemWatcher - это .NET способ обернуть ReadDirectoryChangesW, так что нет, это не помогает.

Garen 28.05.2012 01:42

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

hova 30.05.2012 19:25

И некоторые из этих событий также будут отброшены и никогда не появятся, как и при попытке использовать ReadDirectoryChangesW (). Нарядить его с FSW бесполезно.

Garen 01.06.2012 03:59

Хорошо, замените все вхождения FileSystemWatcher на ReadDirectoryChangesW, и ответ по-прежнему будет ТО ЖЕ. Вам все равно нужно будет определять, когда файлы поступают быстро, и выполнять свою собственную очистку каталога.

hova 01.06.2012 19:34

Нет, это не так, потому что события включают «когда файлы прибывают», которые вы никогда не увидите. Другими словами, ответ на исходный вопрос - НЕТ. И нет абсолютно НИКАКОГО РЕШЕНИЯ, кроме использования другого механизма, такого как ведение журнала изменений или создание минифильтра файловой системы. Как можно использовать ReadDirectoryChangesW () опять таки, чтобы компенсировать недостаток собственного дизайна, как-то «обойти» его? Непонятно.

Garen 02.06.2012 02:57

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

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

Я успешно решил проблему с помощью чего-то похожего. Поставьте события в очередь или запишите их в файл для последующей обработки. Запись их на диск была для меня ключевым моментом. Это может показаться медленным, но диски кэшируются, а накладные расходы меньше, чем у БД. Моя программа отражает около 1 ТБ в день изменений файлов - сотни тысяч файлов в день.

SilentSteel 08.08.2013 03:54

Мы никогда не видели, чтобы ReadDirectoryChangesW был на 100% надежным. Но лучший способ справиться с этим - отделить «отчетность» от «обработки».

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

В ситуациях с высокой загрузкой ЦП вы также можете препятствовать отправке отчетов о событиях-наблюдателях.

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

Lompican 09.02.2014 05:58

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