C#被动扩展当OnNext需要很长时间并且可观察到产生新事件时会发生什么

时间:2013-11-16 12:33:57

标签: c# system.reactive reactive-programming

我是Rx的新手,我在想当IObservable很快产生很多事件并且OnNext需要很长时间时会发生什么。我猜新事件在某种程度上在内部排队,所以我可以运行我们的记忆。我对吗?请考虑以下小例子:

        Subject<int> subject = new Subject<int>();
        subject.ObserveOn(Scheduler.ThreadPool).Subscribe(x => {      Console.WriteLine("Value published: {0}", x); Thread.Sleep(100); },
                     () => Console.WriteLine("Sequence Completed."));

        for (int i = 0; i < 10; i++)
        {
            subject.OnNext(i);
        }

我发布了10个事件,而消费者方法非常慢。处理所有事件,因此必须将其缓存在内存中。如果我发布了很多事件,我将耗尽内存,对吗?或者我会错过什么?

有没有办法限制被动扩展中待处理事件的数量?例如,如果有超过5个待处理事件,我想省略新事件。

1 个答案:

答案 0 :(得分:3)

是的,你是对的,慢的消费者会导致排队。你问的最接近的内置运算符是Observable.Sample - 然而这会使较旧的事件有利于更新的事件。这是更常见的要求,因为它允许你的慢速观察者赶上来。

让我知道Sample是否足够,因为你描述的缓冲行为是一个不寻常的要求 - 它是可以实现的,但是相当复杂,需要相当重要的代码。

编辑 - 如果你像这样使用Sample,它会在每个OnNext之后返回最新的事件(你需要提供一个调度程序才能工作 - 而NewThreadScheduler创建一个线程每个订阅,而不是每个事件:

void Main()
{
    var source = Observable.Interval(TimeSpan.FromMilliseconds(10)).Take(100);

    source.Sample(TimeSpan.Zero, NewThreadScheduler.Default)
        .Subscribe(SlowConsumer);

    Console.ReadLine();
}

private void SlowConsumer(long item)
{    
    Console.WriteLine(item + " " + Thread.CurrentThread.ManagedThreadId);
    Thread.Sleep(TimeSpan.FromSeconds(1));
}