【问题标题】:Using Rx, take the last fired event every 60 seconds使用 Rx,每 60 秒获取最后一次触发的事件
【发布时间】:2012-07-25 18:02:42
【问题描述】:

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

【问题讨论】:

    标签: c# events system.reactive


    【解决方案1】:

    我认为这被过度设计了,你只需要使用Sample,它正是你想要的:

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

    【讨论】:

      【解决方案2】:

      这样做:

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

      【讨论】:

      • 出于好奇,当事件停止超过 60 秒时,此流会发出什么?
      【解决方案3】:

      鉴于 sn-p,在订阅 Observable 之前什么都不会发生。 IIRC,该事件仅在有人调用订阅时才被连接起来(呃,当你处理订阅时它是未连接的)。

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

      【讨论】:

      • 是的 - 你已经完成了相当于没有 Foreach'ing LINQ 语句的操作。将您的活动切换为订阅
      【解决方案4】:

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

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-09
        • 2012-03-25
        相关资源
        最近更新 更多