简体   繁体   English

RX - 可观察序列中元素的组/批突发

[英]RX - Group/Batch bursts of elements in an observable sequence

I have an observable sequence. 我有一个可观察的序列。 When the first element is inserted, I would like to start a timer and batch subsequent inserted elements during the timespan of the timer. 插入第一个元素时, 我想在计时器的时间跨度内启动计时器并批量后续插入的元素。 Then, the timer wouldn't start again until another element is inserted in the sequence. 然后,计时器不会再次启动,直到序列中插入另一个元素。

So something like this: 所以像这样:

--------|=====timespan====|---------------|=====timespan====|-------------->
        1  2 3 4    5                     6 7            8

would produce: 会产生:

[1,2,3,4,5], [6,7,8] 

I tried with Observable.Buffer() and a timespan but from my experimentation, I can see that the timer is started as soon as we subscribe to the observable sequence and is restarted as soon as the previous timer is completed. 我尝试使用Observable.Buffer()和一个时间跨度但是从我的实验中,我可以看到定时器在我们订阅可观察序列时立即启动,并在上一个定时器完成后立即重新启动。

So having the same sequence as the previous example and using the Buffer() with a timespan, I would have something like this: 因此,使用与前一个示例相同的序列并使用带有时间跨度的Buffer(),我会有这样的事情:

|=====timespan====|=====timespan====|=====timespan====|=====timespan====|-->
        1  2 3 4    5                      6 7           8

which would produce this: 哪会产生这个:

[1,2,3,4], [5], [6,7], [8]

Here is how I tested this behavior with the Buffer: 以下是我使用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)));

With the output: 随着输出:

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 => []

Anyone has an idea on how to do this? 任何人都知道如何做到这一点? Thanks in advance! 提前致谢!

Give this a go: 放手一搏:

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)));

I had to change your test code duration for the third timer to make sure the value was outside of the grouped timer. 我必须更改第三个计时器的测试代码持续时间,以确保该值超出了分组计时器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM