Одна из вещей, которые меня долго беспокоили в FileSystemWatcher - это то, как он запускает несколько событий для одного логического изменения файла. Я знаю, почему это происходит, но я не хочу беспокоиться - я просто хочу повторить анализ файла один раз, а не 4-6 раз подряд. В идеале, должно происходить событие, которое срабатывает только тогда, когда заданный файл изменяется, а не каждый шаг на этом пути.
На протяжении многих лет я придумывал различные решения этой проблемы, в разной степени безобразия. Я думал, что Reactive Extensions будет окончательным решением, но есть кое-что, что я не делаю правильно, и я надеюсь, что кто-то может указать на мою ошибку.
У меня есть метод расширения:
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, поэтому я, вероятно, упускаю что-то очевидное. Я делаю это неправильно? Есть ли лучший подход? Спасибо за любые предложения ...