Reactive Extensions缓冲事件直到请求

时间:2016-02-25 14:07:55

标签: c# system.reactive reactive-programming

我准备了一个演示应用程序。

using System.Collections.Concurrent;
using System.Reactive.Linq;

class Program
{
    static void Main(string[] args)
    {
        var stored = new ConcurrentQueue<long>();

        Observable.Interval(TimeSpan.FromMilliseconds(20))
            .Subscribe(it => stored.Enqueue(it));

        var random = new Random();

        Task.Run(async () =>
        {
            while (true)
            {
                await Task.Delay((int)(random.NextDouble() * 1000));
                var currBatch = stored.ToArray();
                for (int i = 0; i < currBatch.Length; i++)
                {
                    long res;
                    stored.TryDequeue(out res);
                }
                Console.WriteLine("[" + string.Join(",", currBatch) + "]");
            }
        });

        Console.ReadLine();
    }
}

它模拟独立的消费者,它以随机的时间间隔发射。在真正的应用程序中,事件源将来自文件系统,但可能是突发性的。

这件事的作用是在并发队列中存储无限量的事件,直到消费者决定使用收集的事件。

我强烈感觉这段代码不安全。是否有可能以纯粹的Rx方式重现这种行为?

如果没有,你能建议更好/更安全的方法吗?

1 个答案:

答案 0 :(得分:2)

你走了:

var producer = Observable.Interval(TimeSpan.FromMilliseconds(20));
var random = new Random();

Task.Run(async () =>
{
    var notify = new Subject<int>();
    producer.Window(() => notify)
        .SelectMany(ev => ev.ToList())
        .Subscribe(currBatch => Console.WriteLine("[" + string.Join(",", currBatch) + "]"));

    while (true)
    {
        await Task.Delay((int)(random.NextDouble() * 1000));
        notify.OnNext(1);
    }
});

Console.ReadLine();