How to extend Throttle Timespan in middle of a long running query?

泪湿孤枕 提交于 2020-01-11 10:29:10

问题


Is it possible to extend Throttle Timespan value in middle of a query? For instance, assuming an example as in 101 Rx Samples Throttle there is this query var throttled = observable.Throttle(TimeSpan.FromMilliseconds(750));.

What if I wanted to change it so that if during the first 500 ms there will be no events, then the throttling value would be extended to, e.g., 1500 ms for every event thereafter.

Would this be a place to use the Switch operator?


回答1:


There is an overload of Throttle that accepts a factory function that takes the source event and produces a "throttle stream" that is an IObservable<T> (T can be any type). Events will be suppressed until the throttle stream emits.

The following example has a stream that pumps every second, with a throttle factory producing a 0.5 second throttle. Thus at start, the source stream is not throttled.

If you enter say, 2, the throttle will change to a two second throttle and all events will be suppressed. Change down to 1 and events will appear again.

void Main()
{
    var throttleDuration = TimeSpan.FromSeconds(0.5);
    Func<long, IObservable<long>> throttleFactory =
        _ => Observable.Timer(throttleDuration);

    var sequence = Observable.Interval(TimeSpan.FromSeconds(1))
                             .Throttle(throttleFactory);

    var subscription = sequence.Subscribe(Console.WriteLine);

    string input = null;
    Console.WriteLine("Enter throttle duration in seconds or q to quit");
    while(input != "q")
    {       
        input = Console.ReadLine().Trim().ToLowerInvariant();
        double duration;

        if(input == "q") break;
        if(!double.TryParse(input, out duration))
        {
            Console.WriteLine("Eh?");
            continue;
        }
        throttleDuration = TimeSpan.FromSeconds(duration);
    }

    subscription.Dispose();
    Console.WriteLine("Done");
}

Because this is a factory function producing the throttle per event, you can create something much more dynamic that returns a throttle stream based on the particular input event.

The idea of a stream used as a control like this is a very common technique used throughout the Rx API and is well worth wrapping your head around: examples of similar uses include the other argument to TakeUntil, the durationSelector in GroupByUntil, the bufferClosingSelector in Buffer.



来源:https://stackoverflow.com/questions/19499469/how-to-extend-throttle-timespan-in-middle-of-a-long-running-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!