逆Observable.Throttle

时间:2014-06-12 10:21:12

标签: system.reactive

我正在寻找一种可观察的扩展方法来进行反向节流。我的意思是让第一个项目通过,然后在适当的时间内忽略项目后面的项目。

input - due time 2
|*.*.*..*..|
output
|*......*..|

请注意,这是一个与下面的问题不同的问题(它们都是相同的)。下面的问题需要一个固定的抑制持续时间,而我需要一个抑制持续时间,每当新项目过早到达时,抑制持续时间会增加。在视觉上,下面列出的解决方案的输出如下:

input - due time 2
|*.*.*..*..|
output
|*...*..*..|

更新

我提出了以下解决方案,但是我对调度程序和并发性知之甚少,以确保锁定足够好。当方法中添加Scheduler参数时,我也不知道如何实现此方法。

    public static IObservable<T> InverseThrottle<T>(this IObservable<T> source, TimeSpan dueTime)
    {
        IDisposable coolDownSupscription = null;
        object subscriptionLock = new object();

        return source
            .Where(i =>
            {
                lock (subscriptionLock)
                {
                    bool result;
                    if (coolDownSupscription == null)
                    {
                        result = true;
                    }
                    else
                    {
                        coolDownSupscription.Dispose();
                        result = false;
                    }

                    coolDownSupscription = Observable
                            .Interval(dueTime)
                            .Take(1)
                            .Subscribe(_ =>
                            {
                                lock (subscriptionLock)
                                {
                                    coolDownSupscription = null;
                                }
                            });
                    return result;
                }
            });
    }

2 个答案:

答案 0 :(得分:3)

你可以使用这样的东西......

source
    .GroupByUntil(
        x => Unit.Default,
        x => x.Throttle(TimeSpan.FromSeconds(100))
    )
    .SelectMany(
        x => x.ToList().Take(1) // yields first item on completion of the observable.
    );

答案 1 :(得分:0)

我建议这个。

public static class IObservable_FirstThenThrottle
{
    public static IObservable<TSource> FirstThenThrottle<TSource>(this IObservable<TSource> source, TimeSpan dueTime)
    {
        var first = source.Take(1);
        var second = source.Skip(1).Throttle(dueTime);
        return first.Merge(second);
    }
}

当第一个项目进入时会触发。然后按dueTime限制剩余的序列。

这是一张大理石图,显示dueTime = 2会发生什么。

source 0-1-2--3--|
result 0------2--3--|