Реактивные Расширения: дроссель/Образец с переменным интервалом

Я имею 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 параметр производит интервал для следующего образца, и первый образец... или взят в первом значении или от дополнительного параметра, я не забочусь.

Я пытался писать это, но я закончил с большой замысловатой конструкцией, которая не работала совершенно верно. Мой вопрос, я могу создать это использование существующих операторов (иначе с остротой)?

7
задан R. Martinho Fernandes 16 August 2010 в 04:01
поделиться

2 ответа

Много часов спустя, немного поспав, я получил это.

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) .

5
ответ дан 7 December 2019 в 12:13
поделиться

Разве это не то, что вы ищете для Observable.BufferWithTime ?

0
ответ дан 7 December 2019 в 12:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: