我一直在使用.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));
答案 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做事方式。