.net Observable.Timer()会导致内存泄漏吗?
最近我注意到我的代码中有一个小错误,它使用了反应式扩展。我订阅了Timer,但从未处理过订阅。这导致内存泄漏 我创建了一个片段,突出了这种危险:.net Observable.Timer()会导致内存泄漏吗?,.net,timer,system.reactive,observable,.net,Timer,System.reactive,Observable,最近我注意到我的代码中有一个小错误,它使用了反应式扩展。我订阅了Timer,但从未处理过订阅。这导致内存泄漏 我创建了一个片段,突出了这种危险: while (true) { Observable.Timer(TimeSpan.Zero, TimeSpan.FromMinutes(1)).Subscribe(Console.WriteLine); } 这是正常的行为吗 当订阅者与应用程序的其余部分失去连接时,调度器不应该持有对计时器的弱引用以使其被垃圾收集吗?这是正常的,也是一项功能
while (true)
{
Observable.Timer(TimeSpan.Zero, TimeSpan.FromMinutes(1)).Subscribe(Console.WriteLine);
}
这是正常的行为吗
当订阅者与应用程序的其余部分失去连接时,调度器不应该持有对计时器的弱引用以使其被垃圾收集吗?这是正常的,也是一项功能
Subscribe()的语义是永远侦听,或者直到Disposed()或OnCompleted()或OnError(),这是第一个。您可以保留对订阅的引用,甚至可以将它们与一个CompositeDisposable
组合,但通常是在一个无限操作符上管理IObservable
生存期的方法(如Timer
)是通过使用一个操作符将终止规则应用于另一个操作符,如Take
(获取x个值)、TakeWhile
(在f(x)
返回true时获取值)或TakeUntil
(获取值直到另一个序列y发出值或完成)
运行Rx操作符不会自动GC'd,除非它们已经完成。
计时器
/间隔
,例如,两者都使用IScheduler
递归地调度它们的下一个值,并且各种调度器的默认实例都可以通过调度器
的静态属性访问。这使得运行ning运算符始终是根运算符,因此无法用于GC。我不同意这个答案。
实际上,您所做的是多余的,因为您使用一个无限循环来创建连续的可观察对象,因此内存泄漏。
删除while循环,只使用一个Observable.Timer,或者更好地使用Observable.Interval。当您不再需要它时,只使用一个实例调用dispose。该代码是一个简化的示例代码,以使问题更加明显。我想作者知道您写了什么。