如何避免在RX中使用Subjects

时间:2014-02-17 08:41:44

标签: c# system.reactive subject

所以我一直在读到Subject<T>使用“不好”的地方 - 而且我同意这个推理。

但是,我正在考虑避免使用它的最佳方法,并举一个例子。

目前我有一个持久化配置类的抽象类,它上面有一个受保护的Save()方法,只要更改属性应该保持该类,就会调用该方法。此消息将消息泵送到Subject<T>,该IObservable<T>通过Observable.FromEventPattern()接口公开,序列化服务侦听并序列化该类。这似乎是当时实现这一目标的最明显,最简单,最快捷的方式。

那么在不使用主题的情况下,RX方式会是什么?我是否会公开一个事件并使用{{1}}订阅它? - 因为这似乎是一种更复杂的方式。

2 个答案:

答案 0 :(得分:14)

使用Subject<T>并不是很糟糕 - 必须有某种方式“进入monad” - 这就是说“得到IObservable<T>”的学术方式。你需要从某个地方开始。

Subject<T>的问题在订阅中使用而不是将现有的observable链接在一起时会产生更多问题。主题应该只存在于你的Rx机器的边缘。

如果所提供的入口点(例如FromEventFromEventPatternFromAsyncReturnToObservable()等)都不适合您,那么使用Subject<T>完全有效。并且没有必要为了方便使用上述其中一个而增加额外的复杂性 - 无论如何,大多数都使用主题或类似主题的结构。

在你的情况下,Subject<T>之类的声音就好了。您可以查看通过AsObservable()公开它以隐藏实现细节。

答案 1 :(得分:1)

一种简单的输入可观察对象的方法是通过操作

private Action<ObservableArgs> _action;

创建可观察的

public IObservable<ObservableArgs> GetObservable()
{
    return Observable.FromEvent<ObservableArgs>>(
                ev => _action += ev, 
                ev => _action -= ev);
}

然后使用添加到可观察对象

public void OnNext(ObservableArgs args)
{
    _action?.Invoke(args);
}