.NET Rx - ReplaySubject缓冲区大小无效

时间:2012-01-31 03:43:18

标签: system.reactive

我一直在使用.NET Reactive Extensions观察日志事件。我正在使用一个派生自IObservable的类并使用ReplaySubject来存储日志,这样我就可以过滤和重放日志(例如:显示所有错误日志,或显示所有详细日志),而不会丢失我已缓冲的日志。

问题是,即使我在主题上设置了缓冲区大小:

this.subject = new ReplaySubject<LogEvent>(10);

当我使用OnNext在无限循环中添加到可观察集合时,我的程序的内存使用量会上升:

internal void WatchForNewEvents()
        {
            Task.Factory.StartNew(() =>
                {
                    while (true)
                    {
                        dynamic parameters = new ExpandoObject();
                        // TODO: Add parameters for getting specific log events

                        if (this.logEventRepository.GetManyHasNewResults(parameters))
                        {
                            foreach (var recentEvent in this.logEventRepository.GetMany(parameters))
                            {
                                this.subject.OnNext(recentEvent);
                            }
                        }

                        // Commented this out for now to really see the memory go up 
                        // Thread.Sleep(1000); 
                    }
                });
        }

ReplaySubject上的缓冲区大小不起作用吗?达到缓冲区大小时似乎没有清除缓冲区。任何帮助非常感谢!

更新:

我添加这样的订阅者(这是错的吗?):

public IDisposable Subscribe(IObserver<LogEvent> observer)
        {
            return this.subject.Subscribe(observer);
        }

...被称为:

// Inserts into UI ListView
    this.logEventObservable.Subscribe(evt => this.InsertNewLogEvent(evt));

1 个答案:

答案 0 :(得分:0)

我不确定这是否是确定的答案,但我怀疑你是因为你正在使用的调度程序的并发性而遇到问题。您在ReplaySubject上调用的构造函数如下所示:

public ReplaySubject(int bufferSize)
    : this(bufferSize, TimeSpan.MaxValue, Scheduler.CurrentThread)
{ }

Scheduler.CurrentThread让我担心。尝试将其更改为Scheduler.ThreadPool,看看是否有帮助。

另外,作为旁注,您似乎将Rx与TPL和老式线程睡眠混合在一起。通常最好避免这样做。您可以将WatchForNewEvents代码更改为:

dynamic parameters = new ExpandoObject();

var newEvents =
    from n in Observable.Interval(TimeSpan.FromSeconds(1.0))
    where this.logEventRepository.GetManyHasNewResults(parameters)
    from recentEvent in
        this.logEventRepository.GetMany(parameters).ToObservable()
    select recentEvent;

newEvents.Subscribe(this.subject);

这是一种非常紧凑的Rx-y做事方式。