【发布时间】:2013-05-07 07:17:13
【问题描述】:
我有一个公开IObservable 状态的 API。但是这个状态取决于一个底层的 observable 源,它必须通过Init 初始化。
我想做的是保护用户不必按正确的顺序做事:按照目前的情况,如果他们在执行Init 之前尝试订阅Status,他们会得到一个例外因为它们的源没有初始化。
所以我有了使用Subject 将两者解耦的天才想法:订阅我的Status 的外部用户只是订阅了主题,然后当他们调用Init 时,我订阅了底层服务使用我的主题。
代码中的想法
private ISubject<bool> _StatusSubject = new Subject<bool>();
public IObservable<bool> Status { get { return _StatusSubject; } }
public void Init()
{
_Connection = new Connection();
Underlying.GetDeferredObservable(_Connection).Subscribe(_StatusSubject);
}
但是,从对虚拟项目的测试来看,问题在于初始化 通过订阅 Subject 来“唤醒”我的底层 Observable,即使还没有人订阅该主题。如果可能的话,我想避免这种情况,但我不确定如何...
(我也注意到 the received wisdom 说“一般规则是,如果你使用一个主题,那么你做错了什么”)
【问题讨论】:
-
为了它的价值,“有状态的”可观察流和
Subject在我的脑海中齐头并进;是的,它通常不受欢迎,但通常你会尝试建立一个无状态的流。如果状态的概念不能从流机制中抽象出来(比如需要特定的引导/初始化),我建议使用Subject;它方式更容易理解和使用。 -
在我看来,避免
Subject的主要原因是人们通常会先达到它并最终得到一个复杂的解决方案(如下面的@Benjol 的解决方案),而没有意识到他们通常是- 实现RX已经作为运营商提供的东西。Subject应该放在要尝试的事情列表的末尾附近。但是一旦你发现你不能以其他方式更简单地做到这一点,那么一定要使用Subject! -
@brandon 这是一个公平的观点;我通常会用主题制作原型,然后向后工作,将它们分解成直接的流。好的答案,顺便说一句
标签: c# system.reactive subject