R. *_*des 7 .net system.reactive
我有一个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);
Run Code Online (Sandbox Code Playgroud)
该intervalSelector参数生成下一个样本的间隔,第一个样本...是从第一个值或另一个参数获取,我不在乎.
我试着写这篇文章,但最后我的结构很复杂,不能正常工作.我的问题是,我可以使用现有的运算符(也就是单行代码)来构建它吗?
很多个小时之后,有一些睡眠,我得到了它.
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);
}
Run Code Online (Sandbox Code Playgroud)
这可以按我的意愿工作:每次产生一个值时x,它会停止产生值,直到intervalSelector(x)时间过去.
| 归档时间: |
|
| 查看次数: |
3323 次 |
| 最近记录: |