使用Rx,每隔60秒进行一次最后一次触发事件

时间:2012-07-25 18:02:43

标签: c# events system.reactive

我有一个事件(可能)每秒触发一次(计时器滴答)。我想做的是每60秒取最后一个刻度EventArgs值(如果在60秒内有新的刻度)。我尝试过这样的事情:

Observable.FromEventPattern(
    h => myThing.SomeEvent += h,
    h => myThing.SomeEvent -= h)
        .Throttle(TimeSpan.FromSeconds(60))
        .TakeLast(1)
        .Do(p => // do something with p);

不幸的是我从未接触过Do方法,而且我不确定我做错了什么?

道歉,如果这是完全错误的,我第一次使用Rx:)

修改:根据以下建议,我将Do更改为Subscribe,但如果我使用Throttle,我仍然无法获得任何结果。我应该使用它吗?

4 个答案:

答案 0 :(得分:13)

我认为这是过度设计的,您只需要使用Sample,它就能完全符合您的要求:

source.Sample(TimeSpan.FromSeconds(60)).Subscribe(x => /* .. */);

答案 1 :(得分:7)

这样做:

Observable.FromEventPattern(h => myThing.SomeEvent += h, h => myThing.SomeEvent -= h)
    .Window(TimeSpan.FromSeconds(60))
    .SelectMany(x => x.TakeLast())
    .Subscribe(x => /* ... */);

答案 2 :(得分:3)

鉴于该片段,在您订阅Observable之前不会发生任何事情。 IIRC,该活动仅在有人致电订阅时才接通(当您处理订阅时,它已取消连接)。

我尽量避免使用Do.可观察值是一个值流,您应该通过在订阅期间传入的方法来处理这些值(以及流结束或错误)。然后变成副作用 - 你在前往OnNext方法的过程中作为价值观做的事情。

答案 3 :(得分:2)

Well Throttle不会解决问题,因为..

油门工作的方式是它等待一段时间暂停一段时间,假设你每秒钟都有一个事件而你的油门是1分钟,你将永远不会看到任何东西。除非您的信息流出现问题,否则会暂停超过1分钟。

Throttle最常用的一个例子就是将它用于自动完成框,你不想在每次按键时发出过滤列表的请求,所以你设置一个让我们说300毫秒的节流,所以当用户停止输入至少300毫秒,您将触发搜索。

我想知道你的解决方案是否会从缓冲区或窗口中受益......我敢打赌,保罗可以找到比我的大脑目前更棒的东西。现在几个月没有使用Rx了:(