如何在长时间运行的查询中间扩展Throttle Timespan?

时间:2013-10-21 16:07:15

标签: c# system.reactive reactive-programming

是否可以在查询中间扩展Throttle Timespan值?例如,假设101 Rx Samples Throttle中的示例存在此查询var throttled = observable.Throttle(TimeSpan.FromMilliseconds(750));

如果我想改变它,如果在前500毫秒内没有事件,那么对于之后的每个事件,限制值将扩展到例如1500毫秒。

这是一个使用Switch运算符的地方吗?

1 个答案:

答案 0 :(得分:6)

Throttle的重载接受一个工厂函数,它接受源事件并产生一个IObservable<T>的“节流”(T可以是任何类型)。在节流流发出之前,将禁止事件。

以下示例有一个每秒泵一次的流,油门工厂产生0.5秒的油门。因此,在开始时,源流不受限制。

如果输入say,2,油门将变为两秒油门,所有事件都将被禁止。更改为1,事件将再次出现。

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");
}

因为这是一个为每个事件产生油门的工厂函数,所以您可以创建更加动态的东西,根据特定的输入事件返回一个油门流。

像这样用作控件的流的想法是在整个Rx API中使用的一种非常常见的技术,非常值得环顾四周:类似用途的示例包括other TakeUntil参数},durationSelector中的GroupByUntilbufferClosingSelector中的Buffer