Одной из вещей, которая долго прослушивала меня о FileSystemWatcher, является способ, которым он увольняет несколько событий за единственное логическое изменение в файле. Я знаю, почему это происходит, но я не хочу должным быть заботиться - я просто хочу повторно проанализировать файл однажды, не 4-6 раз подряд. Идеально, было бы событие, которое только стреляет, когда данный файл сделан, изменившись, а не каждый шаг по пути.
За эти годы я предложил различные решения этой проблемы различных степеней уродства. Я думал, что Реактивные Расширения будут окончательным решением, но существует что-то, что я не делаю правильно, и я надеюсь, что кто-то может указать на мою ошибку.
У меня есть дополнительный метод:
public static IObservable<IEvent<FileSystemEventArgs>> GetChanged(this FileSystemWatcher that)
{
return Observable.FromEvent<FileSystemEventArgs>(that, "Changed");
}
В конечном счете я хотел бы получить одно событие на имя файла, в течение данного периода времени - так, чтобы четыре события подряд с единственным именем файла были уменьшены до одного события, но я ничего не теряю, если несколько файлов изменяются одновременно. BufferWithTime
походит на идеальное решение.
var bufferedChange = watcher.GetChanged()
.Select(e => e.EventArgs.FullPath)
.BufferWithTime(TimeSpan.FromSeconds(1))
.Where(e => e.Count > 0)
.Select(e => e.Distinct());
Когда я подписываюсь на это заметное, единственное изменение в контролируемом файле инициировало мой метод подписки четыре раза подряд, который скорее побеждает цель. Если я удаляю Distinct()
звоните, я вижу, что каждый из четырех вызовов содержит два идентичных события - таким образом, существует некоторое продолжение буферизации. Увеличение TimeSpan передало BufferWithTime
кажется, не имеет никакого эффекта - я пошел целых 20 секунд без любого изменения в поведении.
Это - мой первый набег в Rx, таким образом, я, вероятно, пропускаю что-то очевидное. Я делаю его неправильно? Существует ли лучший подход? Спасибо за любые предложения...
Моя ошибка. Каким-то образом у меня есть несколько FileSystemWatcher, отслеживающих папки друг друга. Наблюдаемый запускался один раз для каждого наблюдателя, но BufferWithTime
, похоже, работает правильно. Мне все еще нужно выяснить, почему мои наблюдатели запускают события для папок, которые, как я думал, они были настроены на игнорирование, но это не имеет ничего общего с Rx или этим вопросом.
На самом деле, может быть, я смогу решить эту проблему и переключиться на одного наблюдателя, отслеживающего родительскую папку, используя Rx для фильтрации событий из папок, которые мне не интересны.
BufferWithTime. Where().Select(...) сделает свою работу, но на самом деле вам нужен Throttle()