我有一个可观察的序列。插入第一个元素时,我想在计时器的时间跨度内启动一个计时器并批量后续插入的元素。然后,计时器不会再次启动,直到序列中插入另一个元素。
这样的事情:
--------|=====timespan====|---------------|=====timespan====|-------------->
1 2 3 4 5 6 7 8
会产生:
[1,2,3,4,5], [6,7,8]
我尝试使用Observable.Buffer()和一个时间跨度,但是从我的实验中,我可以看到定时器在我们订阅可观察序列时立即启动,并在上一个定时器完成后立即重启。
所以使用与前一个示例相同的序列并使用带有时间跨度的Buffer(),我会有这样的事情:
|=====timespan====|=====timespan====|=====timespan====|=====timespan====|-->
1 2 3 4 5 6 7 8
会产生这个:
[1,2,3,4], [5], [6,7], [8]
以下是我使用Buffer测试此行为的方法:
var source = Observable.Concat(Observable.Timer(TimeSpan.FromSeconds(6)).Select(o => 1),
Observable.Timer(TimeSpan.FromSeconds(1)).Select(o => 2),
Observable.Timer(TimeSpan.FromSeconds(3)).Select(o => 3),
Observable.Never<int>());
Console.WriteLine("{0} => Started", DateTime.Now);
source.Buffer(TimeSpan.FromSeconds(4))
.Subscribe(i => Console.WriteLine("{0} => [{1}]", DateTime.Now, string.Join(",", i)));
输出:
4/24/2015 7:01:09 PM => Started
4/24/2015 7:01:13 PM => []
4/24/2015 7:01:17 PM => [1,2]
4/24/2015 7:01:21 PM => [3]
4/24/2015 7:01:25 PM => []
4/24/2015 7:01:29 PM => []
4/24/2015 7:01:33 PM => []
任何人都知道如何做到这一点?提前谢谢!
答案 0 :(得分:6)
放手一搏:
var source = Observable.Concat(Observable.Timer(TimeSpan.FromSeconds(6)).Select(o => 1),
Observable.Timer(TimeSpan.FromSeconds(1)).Select(o => 2),
Observable.Timer(TimeSpan.FromSeconds(4)).Select(o => 3),
Observable.Never<int>());
Console.WriteLine("{0} => Started", DateTime.Now);
source
.GroupByUntil(x => 1, g => Observable.Timer(TimeSpan.FromSeconds(4)))
.Select(x => x.ToArray())
.Switch()
.Subscribe(i => Console.WriteLine("{0} => [{1}]", DateTime.Now, string.Join(",", i)));
我必须更改第三个计时器的测试代码持续时间,以确保该值超出分组计时器。