C# .Net无功扩展';s窗口函数与HistoricalScheduler一起工作不正确
我有1分钟间隔时间序列,并希望将其聚合为5分钟间隔。 用于测试的简单输入类:C# .Net无功扩展';s窗口函数与HistoricalScheduler一起工作不正确,c#,.net,reactive,C#,.net,Reactive,我有1分钟间隔时间序列,并希望将其聚合为5分钟间隔。 用于测试的简单输入类: internal class Item { public int Id { get; set; } public int Value { get; set; } public DateTime Dt { get; set; } } 我已为此任务创建了基于反应的代码: IEnumerable<Item> data = new List<Item>
internal class Item
{
public int Id { get; set; }
public int Value { get; set; }
public DateTime Dt { get; set; }
}
我已为此任务创建了基于反应的代码:
IEnumerable<Item> data = new List<Item> {
new Item { Id = 1, Value = 1, Dt = DateTime.Parse("2018-12-03 08:00:00")},
new Item { Id = 2, Value = 1, Dt = DateTime.Parse("2018-12-03 08:01:00")},
new Item { Id = 3, Value = 1, Dt = DateTime.Parse("2018-12-03 08:02:00")},
new Item { Id = 4, Value = 1, Dt = DateTime.Parse("2018-12-03 08:03:00")},
new Item { Id = 5, Value = 1, Dt = DateTime.Parse("2018-12-03 08:04:00")},
new Item { Id = 6, Value = 1, Dt = DateTime.Parse("2018-12-03 08:05:00")},
new Item { Id = 6, Value = 1, Dt = DateTime.Parse("2018-12-03 08:06:00")},
new Item { Id = 7, Value = 1, Dt = DateTime.Parse("2018-12-03 08:15:00")},
new Item { Id = 8, Value = 1, Dt = DateTime.Parse("2018-12-03 08:16:00")},
new Item { Id = 9, Value = 1, Dt = DateTime.Parse("2018-12-03 08:17:00")},
new Item { Id = 10, Value = 1, Dt = DateTime.Parse("2018-12-03 08:18:00")},
new Item { Id = 11, Value = 1, Dt = DateTime.Parse("2018-12-03 08:19:00")},
new Item { Id = 12, Value = 1, Dt = DateTime.Parse("2018-12-03 08:20:00")},
};
var scheduler = new HistoricalScheduler(DateTime.Parse("2018-12-03 08:00:00"));
var replay = Observable.Generate(
data.GetEnumerator(),
events => events.MoveNext(),
events => events,
events => events.Current,
events => events.Current.Dt,
scheduler);
replay
.Window(TimeSpan.FromMinutes(5), scheduler)
.Subscribe(stream =>
{
var start = scheduler.Now;
stream
.DefaultIfEmpty()
.Aggregate((last, newItem) =>
{
last.Value += newItem.Value;
last.Dt = start.DateTime;
return last;
})
.Where(e => e != null)
.Subscribe(s => Console.WriteLine($"v:{s.Value} t:{s.Dt}"));
});
scheduler.Start();
Console.ReadKey();
我的问题是:为什么8:15:00的间隔是重复的?它是bug还是特性?:)
此外,我发现,这种重复总是出现在时间序列间隔之后。看起来间隙后的第一项被视为单独的窗口间隔
预期产出:
v:5 t:2018/12/03 08:00:00
v:2 t:2018/12/03 08:05:00
v:5 t:2018/12/03 08:15:00
v:1 t:2018/12/03 08:20:00
具有间隔开始日期的5分钟聚合间隔。为什么间隔后的间隔被拆分为2?这似乎是使用局部声明变量的副作用 规则是永远不要将状态混入可观察状态 以下是工作代码:
IEnumerable<Item> data = new List<Item>
{
new Item { Id = 1, Value = 1, Dt = DateTime.Parse("2018-12-03 08:00:00")},
new Item { Id = 2, Value = 1, Dt = DateTime.Parse("2018-12-03 08:01:00")},
new Item { Id = 3, Value = 1, Dt = DateTime.Parse("2018-12-03 08:02:00")},
new Item { Id = 4, Value = 1, Dt = DateTime.Parse("2018-12-03 08:03:00")},
new Item { Id = 5, Value = 1, Dt = DateTime.Parse("2018-12-03 08:04:00")},
new Item { Id = 6, Value = 1, Dt = DateTime.Parse("2018-12-03 08:05:00")},
new Item { Id = 6, Value = 1, Dt = DateTime.Parse("2018-12-03 08:06:00")},
new Item { Id = 7, Value = 1, Dt = DateTime.Parse("2018-12-03 08:15:00")},
new Item { Id = 8, Value = 1, Dt = DateTime.Parse("2018-12-03 08:16:00")},
new Item { Id = 9, Value = 1, Dt = DateTime.Parse("2018-12-03 08:17:00")},
new Item { Id = 10, Value = 1, Dt = DateTime.Parse("2018-12-03 08:18:00")},
new Item { Id = 11, Value = 1, Dt = DateTime.Parse("2018-12-03 08:19:00")},
new Item { Id = 12, Value = 1, Dt = DateTime.Parse("2018-12-03 08:20:00")},
};
var scheduler = new HistoricalScheduler(DateTime.Parse("2018-12-03 08:00:00"));
var source =
Observable
.Generate(
data.GetEnumerator(),
events => events.MoveNext(),
events => events,
events => events.Current,
events => events.Current.Dt,
scheduler);
source
.Window(TimeSpan.FromMinutes(5), scheduler)
.SelectMany(stream =>
stream
.Aggregate(
new Item() { Value = 0, Dt = scheduler.Now.DateTime },
(a, x) => new Item()
{
Value = a.Value + x.Value,
Dt = x.Dt,
}))
.Subscribe(s => Console.WriteLine($"v:{s.Value} t:{s.Dt}"));
scheduler.Start();
IEnumerable数据=新列表
{
新项{Id=1,Value=1,Dt=DateTime.Parse(“2018-12-03 08:00:00”)},
新项{Id=2,Value=1,Dt=DateTime.Parse(“2018-12-03 08:01:00”)},
新项{Id=3,Value=1,Dt=DateTime.Parse(“2018-12-03 08:02:00”)},
新项{Id=4,Value=1,Dt=DateTime.Parse(“2018-12-03 08:03:00”)},
新项{Id=5,Value=1,Dt=DateTime.Parse(“2018-12-03 08:04:00”)},
新项{Id=6,Value=1,Dt=DateTime.Parse(“2018-12-03 08:05:00”)},
新项{Id=6,Value=1,Dt=DateTime.Parse(“2018-12-03 08:06:00”)},
新项{Id=7,Value=1,Dt=DateTime.Parse(“2018-12-03 08:15:00”)},
新项{Id=8,Value=1,Dt=DateTime.Parse(“2018-12-03 08:16:00”)},
新项{Id=9,Value=1,Dt=DateTime.Parse(“2018-12-03 08:17:00”)},
新项{Id=10,Value=1,Dt=DateTime.Parse(“2018-12-03 08:18:00”)},
新项{Id=11,Value=1,Dt=DateTime.Parse(“2018-12-03 08:19:00”)},
新项{Id=12,Value=1,Dt=DateTime.Parse(“2018-12-03 08:20:00”)},
};
var调度程序=新的历史调度程序(DateTime.Parse(“2018-12-03 08:00:00”);
变量源=
可观察
.产生(
data.GetEnumerator(),
events=>events.MoveNext(),
事件=>事件,
events=>events.Current,
events=>events.Current.Dt,
调度程序);
来源
.Window(TimeSpan.FromMinutes(5),调度程序)
.SelectMany(流=>
流动
.合计(
新项(){Value=0,Dt=scheduler.Now.DateTime},
(a,x)=>新项目()
{
值=a.值+x.值,
Dt=x.Dt,
}))
.Subscribe(s=>Console.WriteLine($“v:{s.Value}t:{s.Dt}”);
scheduler.Start();
这将产生:
v:5 t:2018/12/03 08:04:00
v:2 t:2018/12/03 08:06:00
v:1 t:2018/12/03 08:15:00
v:4 t:2018/12/03 08:19:00
v:1 t:2018/12/03 08:20:00
v:5 t:2018/12/03 08:04:00
v:2T:2018/12/03 08:06:00
v:1 t:2018/12/03 08:15:00
v:4 t:2018/12/03 08:19:00
v:1 t:2018/12/03 08:20:00
当我运行您的代码时,我在
events=>events.Current.Dt,
行上得到一个NRE。对不起,我已经修复了错误并更新了代码。否,根据输入数据和窗口设置更正结果,必须是:v:5t:2018/12/03 08:00:00
v:2t:2018/12/03 08:05:00v:5t:2018/12/03 08:15:00
v:1t:2018/12/03 08:20:00
5分钟的聚合间隔和间隔开始日期。
v:5 t:2018/12/03 08:04:00
v:2 t:2018/12/03 08:06:00
v:1 t:2018/12/03 08:15:00
v:4 t:2018/12/03 08:19:00
v:1 t:2018/12/03 08:20:00