Observable.Timer()会导致内存泄漏吗?

时间:2011-06-05 22:13:37

标签: .net timer system.reactive observable

最近我注意到我的代码中有一个使用Reactive Extensions的小错误。我订阅了Timer,但我从未处理过我的订阅。这导致内存泄漏。

我创建了一个片段,突出了这个危险:

while (true)
{
    Observable.Timer(TimeSpan.Zero, TimeSpan.FromMinutes(1)).Subscribe(Console.WriteLine);
}

这是正常行为吗?

当订阅者与应用程序的其余部分失去连接时,调度程序是否应该保留对计时器的弱引用以使其被垃圾收集?

3 个答案:

答案 0 :(得分:6)

可以保留对订阅的引用,甚至将它们与CompositeDisposable结合起来,但通常的方法是在一个无限运算符上管理IObservable生命周期(如Timer)是通过使用将终止规则应用于其他规则的运算符,例如Take(取x值),TakeWhile(在f(x)返回true时取值)或{{ 1}}(取值直到另一个序列, y ,发出一个值或完成)。

运行Rx运算符不会自动GC,除非它们已完成。例如,TakeUntil / Timer都使用Interval递归调度其下一个值,并且各种调度程序的默认实例都可以通过IScheduler的静态属性访问。这使得运行的操作员始终具有根,因此不适用于GC。

答案 1 :(得分:4)

这是正常的,并且是功能

Subscribe()的语义是永远监听,或直到Disposed()或OnCompleted()或OnError(),它们首先出现。

答案 2 :(得分:1)

我不同意答案。 你正在做的事情是多余的,因为你使用无限循环来创建连续的observable,因此内存泄漏。 删除while循环,只有一个Observable.Timer,甚至更好地使用Observable.Interval。只有一个例子,当你不再需要它时,就可以对它进行处理。