Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 可观察:在源完成之前,每隔一段时间获取最新值_C#_System.reactive - Fatal编程技术网

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输入,时间间隔)
其中应:

  • 输入发出第一项后立即发出第一项
  • 从那时起,在以后的固定时间间隔内,发出由输入生成的最新项目
  • 输入完成(或失败)时完成(或失败)
  • 就大理石而言,假设间隔=2个时间单位,如下所示:

    时间 1. 2. 3. 4. 5. 6. 7. 8. 9 10 11 12 13 14 15 输入 A. B C D E F(完整) 输出 A. B D D E E 完成(不再发射F)
    我现在已经做了以下工作-我认为它是可行的,但我会把它打开,以防有人能想到一种更优雅的方式(或者能想到我当前实现的问题)

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