C# 可观察:在源完成之前,每隔一段时间获取最新值
我正在寻找一个可观察的选择器,其签名类似于:C# 可观察:在源完成之前,每隔一段时间获取最新值,c#,system.reactive,C#,System.reactive,我正在寻找一个可观察的选择器,其签名类似于: static IObservable<T> TakeLatest(this IObservable<T> input, TimeSpan interval) static IObservable TakeLatest(此IObservable输入,时间间隔) 其中应: 输入发出第一项后立即发出第一项 从那时起,在以后的固定时间间隔内,发出由输入生成的最新项目 输入完成(或失败)时完成(或失败) 就大理石而言,假设间隔=2个
static IObservable<T> TakeLatest(this IObservable<T> input, TimeSpan interval)
static IObservable TakeLatest(此IObservable输入,时间间隔)
其中应:
我现在已经做了以下工作-我认为它是可行的,但我会把它打开,以防有人能想到一种更优雅的方式(或者能想到我当前实现的问题)
static IObservable TakeLatest(此IObservable输入、时间间隔、isScheduler调度程序)=>input
.FirstAsync()
.Select(=>Observable.Interval(Interval,scheduler).StartWith(0))
.Switch()
.CombineTest(输入,(a,b)=>(a,b))
.DistinctUntilChanged(x=>x.a)
.选择(x=>x.b)
.TakeUntil(input.LastAsync());
这可能正是您想要的。不过我还没有测试过
/// <summary>Samples the source observable sequence at each interval,
/// allowing repeated emissions of the same element.</summary>
public static IObservable<T> SampleWithDuplicates<T>(this IObservable<T> source,
TimeSpan interval, IScheduler scheduler = null)
{
scheduler ??= DefaultScheduler.Instance;
return source.Publish(published => Observable
.Interval(interval, scheduler)
.WithLatestFrom(published, (_, x) => x)
.Merge(published.FirstAsync())
.TakeUntil(published.LastOrDefaultAsync()));
}
///在每个间隔对源可观测序列进行采样,
///允许相同元素的重复排放。
具有重复项的公共静态IObservable样本(此IObservable源,
TimeSpan间隔,IsScheduler调度程序=null)
{
调度器???=DefaultScheduler.Instance;
返回source.Publish(published=>Observable
.间隔(间隔,调度程序)
.WithLatestFrom(已发布,(x)=>x)
.Merge(已发布的.FirstAsync())
.TakeUntil(published.LastOrDefaultAsync());
}
我想你想要@Liam,但我认为这不够用(如果错了,请纠正我)。例如,如果源产生一个值,我认为debounce最多会发出一次该项;在我的场景中,可能需要多次发射同一个项目(如果没有其他更近期的项目可用),我认为您可能希望将其与之结合。问题是我只知道rxjs,不知道rx.Net,所以我不能100%确定运营商是如何映射的。因此,您可能只搜索了一条注释,以查找运算符。如果您还希望能够动态更改采样间隔,请看一个问题。一个问题是,输入
序列订阅了三次,因此它不能正确处理冷序列。你可能需要发布这个输入序列。效果确实很好!(它不会发出第一项,但这当然很容易添加)。谢谢你,你能给出正确的答案吗?因为所有建议的解决方案都没有OP预期的效果?@DmitryStepanov好的,完成了。不过它还没有经过测试。@DmitryStepanov显然OP的大理石图有竞争条件,因为间隔大约在源序列发出项目的同时滴答作响。所以不能保证输出总是B D E。@TheodorZoulias-一个非常好的查询!
/// <summary>Samples the source observable sequence at each interval,
/// allowing repeated emissions of the same element.</summary>
public static IObservable<T> SampleWithDuplicates<T>(this IObservable<T> source,
TimeSpan interval, IScheduler scheduler = null)
{
scheduler ??= DefaultScheduler.Instance;
return source.Publish(published => Observable
.Interval(interval, scheduler)
.WithLatestFrom(published, (_, x) => x)
.Merge(published.FirstAsync())
.TakeUntil(published.LastOrDefaultAsync()));
}