我正在寻找一种可观察的扩展方法来进行反向节流。我的意思是让第一个项目通过,然后在适当的时间内忽略项目后面的项目。
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;
}
});
}
答案 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--|