6

我有一个事件(可能)每秒触发一次(计时器滴答声)。我想做的是EventArgs每 60 秒取最后一个刻度的值(如果在这 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 :)

编辑:根据下面的建议,我改为DoSubscribe但如果我使用 ,我仍然没有得到任何结果Throttle。我应该使用它吗?

4

4 回答 4

14

我认为这是过度设计的,您只需要使用Sample,它就可以满足您的要求:

source.Sample(TimeSpan.FromSeconds(60)).Subscribe(x => /* .. */);
于 2012-07-26T10:44:54.863 回答
7

做这个:

Observable.FromEventPattern(h => myThing.SomeEvent += h, h => myThing.SomeEvent -= h)
    .Window(TimeSpan.FromSeconds(60))
    .SelectMany(x => x.TakeLast())
    .Subscribe(x => /* ... */);
于 2012-07-26T09:58:24.873 回答
3

鉴于该片段,在您订阅 Observable 之前什么都不会发生。IIRC,该事件仅在有人调用订阅时才连接(呃,当您处理订阅时未连接)。

我尽量避免使用 Do。可观察对象是一个值流,您应该通过订阅期间传入的方法真正处理这些值(以及流结束或错误)。然后,Do 变成了一个副作用——当值在传递到 OnNext 方法的过程中,你会做一些事情。

于 2012-07-25T20:31:23.743 回答
2

油门不会解决问题,因为..

油门的工作方式是在给定的时间内等待暂停,假设您每秒收到一个事件,而您的油门是 1 分钟,您将永远看不到任何东西。除非您的直播出现问题并且突然间停顿超过 1 分钟。

Throttle 最常用的示例之一是将其用于 AutoComplete 框,您不想在每次击键时触发过滤列表的请求,因此您将限制设置为 300 毫秒,因此当用户停止时输入至少 300 毫秒,您将触发搜索。

我想知道您的解决方案是否会从缓冲区或窗口中受益……我敢打赌,保罗现在能想出比我的大脑更棒的东西。几个月来没有太多使用 Rx :(

于 2012-07-26T09:25:36.860 回答