В документах MSDN содержится критическое примечание, которое может помочь вам более надежно обнаруживать изменения:
Сохраняйте код обработки событий коротким
насколько это возможно.
Я подозреваю (но не знаю наверняка), что это происходит потому, что события файловой системы вызываются в основном потоке наблюдателя, поэтому каждый раз, когда вы тратите обработку событий, создается окно, в котором изменения могут остаться незамеченными. То, как вы описали свое решение, похоже, что вы выполняете ввод-вывод в обратном вызове (записи в ваш файл журнала изменений XML), и это, безусловно, может оказаться слишком большой работой, чтобы выполнить ее в соответствии с критериями в API. Docs. Если у вас есть много работы для события, передайте ваши события для обработки в отдельном потоке, чтобы вы могли вернуться к просмотру файловой системы как можно скорее.
Один относительно простой способ сделать это - использовать ThreadPool.QueueUserWorkItem . Это означает, что ваш журнал изменений по-прежнему не будет на 100% синхронизирован с состоянием файловой системы (из-за задержки, вызванной использованием отдельных потоков и очереди), но он может быть более точным, и это, кажется, является вашей главной задачей. Вам нужно убедиться, что ваш WaitCallback
, вызванный пулом потоков, является поточно-ориентированным (например, записи в ваш журнал изменений не происходят одновременно без lock()
или подобного), и знать, что нет никаких гарантий, что записи в журнале изменений будет написано в том порядке, в котором они произошли (хотя мне сомнительно, гарантирует ли это FileSystemWatcher
в любом случае).
Также в соответствии с инструкциями для API - убедитесь, что вы фильтруете возможный набор событий, чтобы вам перезванивали только те, которые вам абсолютно необходимо видеть:
Чтобы избежать переполнения буфера, используйте NotifyFilter
и
IncludeSubdirectories properties
так что вы можете отфильтровать
уведомления о нежелательных изменениях.