这里的问题(正如 Shlomo 所提到的)是我们需要在t1 事件发生之前打开t2 中的窗口。不幸的是,这是不可能的,因为一旦我们到达t1 中的事件,我们就已经过了需要在t2 中打开窗口的地步。
我们可以做的是使用Delay() 将t2 及时向前移动。如果我们将其抵消x(之前的时间),我们可以将问题重新定义为“获取t2 中发生在t1 窗口打开和t1 + x + y 关闭的事件。我们可以使用GroupJoin解决这个问题。
var scheduler = new HistoricalScheduler();
var t1 = Observable.Interval(TimeSpan.FromMilliseconds(200), scheduler)
.Select(l => (char)('A' + l));
var t2 = Observable.Interval(TimeSpan.FromMilliseconds(100), scheduler);
var x = TimeSpan.FromMilliseconds(100); //before time
var y = TimeSpan.FromMilliseconds(100); //after time
var delayedT2 = t2.Delay(x, scheduler);
var g = t1.GroupJoin(delayedT2 ,
_ => Observable.Timer(x + y, scheduler),
_ => Observable.Empty<Unit>(scheduler),
(a, b) => new { a, b}
);
scheduler.Start();
这给出了结果:
{ A, [1,2] }
{ B, [3,4] }
{ C, [5,6] }
这个结果仍然不是你所期望的。这是因为在您的示例中,t2 事件发生在完全相同的瞬间t1 事件中。在这种情况下,首先处理t1 + y 事件并在可以包含t2 事件之前关闭窗口。这意味着我们有效地获得了(t1-01:00) <= t1 < (t1 + 01:00)。例如。 A 的窗口是 01:0000 - 02.9999... 这就是为什么不包括在 03:00 发生的 3。
只需在我们的y 时间上添加一个刻度,即可将其修复为包容性
var y = TimeSpan.FromMilliseconds(100).Add(TimeSpan.FromTicks(1));