System.Reactive:时间戳字段的基于时间的缓冲区

问题描述

我在我的 C# 项目中使用 Reactive 库根据配置的策略对数据进行分组。所有这些数据都实现了以下接口

public interface IPoint
{
    object Value { get; }
    DateTimeOffset Timestamp { get; }
}

我必须实施的分组策略之一是创建固定时间大小的不可重叠组,可以使用 Buffer(TimeSpan) 函数查看 Reactive 文档。这正是我需要的,但我需要使用对象的 Timestamp 属性中定义的时间戳,而不是使用运行时计算的时间戳。

我找到了 this solution,这似乎很有效:

public void Subscribe(Action<IEnumerable<IPoint>> callback)
{
    long windowSizeTicks = TimeRange.Ticks;    // TimeRange is my TimeSpan "buffer" size

    dataPoints.GroupByUntil(x => x.Timestamp.Ticks / windowSizeTicks,g => dataPoints.Where(x => x.Timestamp.Ticks / windowSizeTicks != g.Key))
              .SelectMany(x => x.ToList())
              .Subscribe(callback);
    // dataPoints is ISubject<IPoint>
}

解决方案仅根据 Ticks 被 TimeRange 的可分性创建组,如果第一项不能被它整除,则无法正常工作。

一个例子来解释我的意思:考虑以下几点

Value: 1,Timestamp: "2021-04-26T00:00:01"
Value: 2,Timestamp: "2021-04-26T00:00:02"
Value: 3,Timestamp: "2021-04-26T00:00:03"
Value: 4,Timestamp: "2021-04-26T00:00:04"

和 2 秒的“缓冲区大小”,我希望它们被分组为 [1,2],[3,4],但我收到的是 [1],[2,3],[4]。发生这种情况是因为创建分组键时考虑的是绝对时间,而不是与数据列表开始的差异。

我可以通过这种方式保存第一项的时间戳并更改分组功能,但我认为(或者至少我希望)可能有更好的解决方案:

public void Subscribe(Action<IEnumerable<IPoint>> callback)
{
    long windowSizeTicks = TimeRange.Ticks;    // TimeRange is my TimeSpan "buffer" size

    dataPoints.GroupByUntil(x => (x.Timestamp.Ticks - firstPoint.Timestamp.Ticks) / windowSizeTicks,g => dataPoints.Where(x => (x.Timestamp.Ticks - firstPoint.Timestamp.Ticks) / windowSizeTicks != g.Key))
              .SelectMany(x => x.ToList())
              .Subscribe(callback);
    // dataPoints is ISubject<IPoint>
}

我是 Reactive 的新手,欢迎提出任何有用的评论

谢谢。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...