Rx订阅和垃圾收集

  • 本文关键字:Rx .net f# system.reactive
  • 更新时间 :
  • 英文 :


是否需要将IObservable.Subscribe返回的IDisposable分配给变量以保护订阅不被垃圾收集,或者活动订阅的存在是否足够?

我的用例:我从现有的可观察对象(示例中为myObservable)创建一个一次性可观察对象:

myObservable.Take(1).Subscribe(fun v -> printfn "One-shot: %A" v) |> ignore

是的,有活动订阅就足够了。GC阻止对订阅的引用链最终从第一个可观察到的源开始,因此当流源处于活动状态时,订阅也处于活动状态。如果流源本身被收集,那么您的订阅将随之消亡,但这没关系,因为无论如何都不会再次调用它。

另一方面,一旦您的订阅接收到一个脉冲,.Take(1)实现将断开它与源的连接,从而允许收集它。

在Rx.NET 2.2中没有Finaliser的用法,因此您的订阅永远不会因为被垃圾收集而被处理。

如果不将订阅分配给变量并显式处理它,它将继续运行,直到终止(OnComplete/OnError)。这里概述了这一点——http://introtorx.com/Content/v1.0.10621.0/03_LifetimeManagement.html#Finalizers

因此,通过不将订阅分配给变量,您就失去了尽早处置订阅的能力。即,如果用户想在返回结果之前取消操作,则您将失去此功能。

这种行为的证明(在C#中,对不起)

var myObservable = Observable.Timer(TimeSpan.FromSeconds(1));
myObservable.Take(1).Subscribe(v => Console.WriteLine($"One-shot: {v}"));
//Force full GC.
GC.Collect();
//Wait for any Finalizers
GC.WaitForPendingFinalizers();
//Then clear out anything kept by finalizers.
GC.Collect();
//We will still see "One-shot: 0" written to the console.

相关内容

  • 没有找到相关文章

最新更新