.Dispose()和.OnCompleted()在Subject上的调用有什么区别?
通常,当订阅在代码中的任何地方都不再有用时,我会释放订阅以停止侦听一个可观察到的主题,并完成一个主题,
发布于 2020-10-05 14:42:41
根据文档的Subject<T>.Dispose方法:
释放
Subject<T>类的当前实例使用的所有资源,并取消订阅所有观察者。
在处理Subject之后,尝试使用它做任何事情,似乎都会导致ObjectDisposedException。例如,您不能将Subscribe转到已释放的Subject。在释放Subject时处于活动状态的任何订阅也将被释放,未订阅的观察者将而不是接收OnCompleted通知。
相反,通过调用其OnCompleted方法完成的主题仍然可以在任何时候被订阅,在这种情况下,订阅的观察者将立即收到OnCompleted通知。当然,如果完成的主题是像ReplaySubject这样的缓冲类型之一,那么观察者将在最终的OnCompleted之前收到许多OnCompleted通知。
就我个人而言,我会考虑将Dispose调用到即将被丢弃的ReplaySubject,以加速恢复其内部缓冲区所使用的内存。不过,我不确定这是否会产生任何不同,因为通常情况下,Dispose应该释放非托管资源,并且缓冲区使用的内存很可能是托管的。
发布于 2020-10-05 13:37:06
通常,我将订阅处理为停止收听可观察到的内容,并在代码中的任何地方不再有用时完成主题。
我觉得你倒过来了。我不熟悉rx.net,但我知道IDisposable和可观察的模式。IDisposable用于将资源从对象中释放出来,当您完成它时,它就不再有用了。OnCompleted用于您完成观察(提供程序已经完成发送通知),即使该对象可能还有其他用途。
发布于 2020-10-06 01:28:43
在主题上调用.Dispose()和.OnCompleted()有一个非常重要的语义区别。
请考虑以下代码:
Subject<int> subject = new Subject<int>();
IObservable<int[]> query = subject.ToArray();
IDisposable subscription =
query
.Subscribe(xs => Console.WriteLine(String.Concat(xs)));
subject.OnNext(1);
subject.OnNext(2);如果然后调用subject.OnCompleted(),就会将12写入控制台。但是,如果我调用subject.Dispose(),则不会打印任何内容。
一些操作符,比如我的示例代码中的.ToArray(),期望.OnCompleted()调用产生任何值。
了解您在subject上执行的查询以了解如何正确结束它非常重要--在某些情况下,这两种方法都是有效的。
不过,我觉得你在处理订阅和完成主题方面做的是对的。
https://stackoverflow.com/questions/64209374
复制相似问题