我有一个事件(可能)每秒触发一次(计时器滴答)。我想做的是每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
,我仍然无法获得任何结果。我应该使用它吗?
答案 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了:(