【问题标题】:Buffer operator with count and time conditions具有计数和时间条件的缓冲区运算符
【发布时间】:2014-04-04 15:35:03
【问题描述】:

我有一个非常健谈的序列,我试图通过批量处理事件来提高它的效率。带有时间和计数条件的 Buffer 运算符似乎符合我的要求,除了一个细微差别。当您使用此重载时,无论缓冲区中是否有任何项目,订阅都会在指定的时间延迟后收到通知。这真的很烦人,因为大多数时候我的订阅从缓冲区操作员那里得到一个空列表。考虑到它是一个订阅者在 UI 线程上的多线程应用程序,事实证明它不是批量处理项目的最佳方法。我想知道是否有一种方法可以使用可用的运算符来创建一个序列,当缓冲区中存在一定数量的项目时,或者当某个时间已经过去时,该序列会触发,但当且仅当有任何项目时缓冲区。我知道我可以这样做:

sequence.Buffer(TimeSpan.FromSeconds(5), 1).Where(e=>e.Count > 0)

但我想知道是否有其他方法可以做到这一点,因为不知何故我觉得这不是最好的方法。

【问题讨论】:

    标签: c# .net system.reactive


    【解决方案1】:

    我看不出有什么理由担心这个 - 你有一个惯用的解决方案。空缓冲区是信息,因此框架实现返回它是合理的。无论如何,任何其他方法都可以有效地在内部做同样的事情。

    当我发现自己在使用一小组标准运算符时,我经常将它们包装在一种更具解释性的扩展方法中。例如:

    public static class ObservableExtensions
    {
        public static IObservable<IList<T>> ToNonEmptyBuffers<T>(
            this IObservable<T> source,
            TimeSpan timespan,
            int count,
            IScheduler scheduler = null)
        {
            scheduler = scheduler ?? Scheduler.Default;
            return source.Buffer(timespan, count, scheduler ?? Scheduler.Default)
                         .Where(buffer => buffer.Count > 0);
        }
    }
    

    允许:

    sequence.ToNonEmptyBuffers(TimeSpan.FromSeconds(5), 1);
    

    【讨论】:

      【解决方案2】:

      为了“Rx-i-ness”,我将以下内容抛诸脑后。

      就个人而言,我认为詹姆斯的回答就足够了(在很多情况下可能会更好)。唯一的区别(就输出而言)是缓冲区计时器仅在产生新项目时启动。这就是我们不需要过滤掉空缓冲区的原因。话虽如此,这可能不是最有效的解决方案。它只是在这里展示组合的力量。

      var batches = source
              .GroupByUntil(
                  // This means we're not really grouping, but windowing.
                  // granted, if we needed to group our batches, this is useful!
                  x => 0,
                  group => Observable.Amb(
                      // this means we get a max of 11 per batch
                      group.Skip(10),
                      // This means we get a max batch time of 10 seconds
                      group.Take(1).Delay(TimeSpan.FromSeconds(10))
              ))
              // Since GroupByUntil gives us windows, we can ToArray them.
              .SelectMany(x => x.ToArray());
      

      【讨论】:

        猜你喜欢
        • 2022-01-11
        • 2018-01-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多