首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >subject.Dispose()与subject.OnCompleted()

subject.Dispose()与subject.OnCompleted()
EN

Stack Overflow用户
提问于 2020-10-05 13:15:53
回答 3查看 885关注 0票数 1

.Dispose().OnCompleted()Subject上的调用有什么区别?

通常,当订阅在代码中的任何地方都不再有用时,我会释放订阅以停止侦听一个可观察到的主题,并完成一个主题,

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 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应该释放非托管资源,并且缓冲区使用的内存很可能是托管的。

票数 0
EN

Stack Overflow用户

发布于 2020-10-05 13:37:06

通常,我将订阅处理为停止收听可观察到的内容,并在代码中的任何地方不再有用时完成主题。

我觉得你倒过来了。我不熟悉rx.net,但我知道IDisposable和可观察的模式。IDisposable用于将资源从对象中释放出来,当您完成它时,它就不再有用了。OnCompleted用于您完成观察(提供程序已经完成发送通知),即使该对象可能还有其他用途。

票数 0
EN

Stack Overflow用户

发布于 2020-10-06 01:28:43

在主题上调用.Dispose().OnCompleted()有一个非常重要的语义区别。

请考虑以下代码:

代码语言:javascript
复制
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上执行的查询以了解如何正确结束它非常重要--在某些情况下,这两种方法都是有效的。

不过,我觉得你在处理订阅和完成主题方面做的是对的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64209374

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档