Я имею IObservable
это производит значения наугад интервалы, и я хочу отрегулировать эту последовательность. Одна вещь, которую я узнал, состоит в том что Throttle
определением оператора "регулировки" не является то же как мое.
Throttle
только производит значения после того, как указанный интервал протекает с тишиной (это производит последнее замеченное значение). Я думал, регулируя, будет означать производить значения в указанном интервале (если нет тишина, конечно).
Скажите, я ожидал Observable.Interval(100).Select((_,i) => i).Throttle(200)
произвести (по модулю любые проблемы производительности/синхронизации) четные числа, так как я регулирую его для "полуускорений". Однако та последовательность не производит значения вообще, потому что никогда нет периода тишины длины 200.
Так, я обнаружил это Sample
на самом деле делает поведение "регулировки", которое я хочу. Observable.Interval(100).Select((_,i) => i).Sample(200)
производит (снова, по модулю любые проблемы производительности/синхронизации) последовательность четных чисел.
Однако у меня есть еще одна проблема: интервал варьируется, в зависимости от последнего "выбранного" значения. То, что я хочу, должно записать оператор, который похож на это:
public static IObservable<T> Sample<T>(this IObservable<T> source, Func<T, TimeSpan> intervalSelector);
intervalSelector
параметр производит интервал для следующего образца, и первый образец... или взят в первом значении или от дополнительного параметра, я не забочусь.
Я пытался писать это, но я закончил с большой замысловатой конструкцией, которая не работала совершенно верно. Мой вопрос, я могу создать это использование существующих операторов (иначе с остротой)?
Много часов спустя, немного поспав, я получил это.
public static IObservable<T> Sample<T>(this IObservable<T> source, Func<T, TimeSpan> intervalSelector)
{
return source.TimeInterval()
.Scan(Tuple.Create(TimeSpan.Zero, false, default(T)), (acc, v) =>
{
if(v.Interval >= acc.Item1)
{
return Tuple.Create(intervalSelector(v.Value), true, v.Value);
}
return Tuple.Create(acc.Item1 - v.Interval, false, v.Value);
})
.Where(t => t.Item2)
.Select(x => x.Item3);
}
Это работает так, как я хочу: каждый раз, когда он производит значение x
, он перестает производить значения, пока не пройдет время intervalSelector (x)
.
Разве это не то, что вы ищете для Observable.BufferWithTime ?