0

我正处于学习 Rx 的早期阶段,并且遇到了 Subject 课程。我不太明白为什么这个类存在。我知道它同时实现了 IObservable 和 IObserver,但是 Subjects 有什么用?

据我所知,他们可以充当源和一群订阅者之间的代理,但订阅者不能直接订阅源吗?当我看到 Subject 的实例被用作可观察对象和观察者时,我会感到困惑。

我确信我在这里没有得到一些基本事实,但我不知道主题给游戏带来了什么。我想我正在寻找一些基本的(但希望是现实世界)示例,说明主题何时有用,何时无用(因为我还读过主题通常不被使用,替换为 Observable.Create)。

4

2 回答 2

1

首先,很多人会告诉你Subject<T> 属于,因为它违反了 Rx 框架中的其他一些原则/模式。

也就是说,它们充当 anIObservable或 an IObserver,因此您可以从中获得一些有用的功能 - 我通常在初始开发阶段使用它们:

  • 某种“调试点”,我可以在其中订阅IObservable与 a 内联的链Subject<T>,并使用调试器检查内容。

  • 一个“按需观察”,我可以手动调用OnNext并传入我想注入流的数据

  • 曾经使用它们来复制ConnectableObserable现在所做的事情 - 多个订阅者的“广播”机制到单个Observable,但现在可以完成Publish

  • 不同系统之间的桥接层;同样,现在对于各种FromAsync,FromEvent扩展,这在很大程度上是不必要的,但它们仍然可以这样使用(基本上,“旧”系统将事件注入Subject<T>via OnNext,然后从正常的 Rx 流程开始。

于 2013-01-31T22:41:55.403 回答
0

使用主题意味着我们现在正在管理状态,这可能会发生变化。变异状态和异步编程很难做到正确。此外,许多运算符(扩展方法)都经过精心编写,以确保订阅和序列的正确和一致的生命周期得以维持。当你介绍主题时,你可以打破这一点。

Create 方法相对于主题的一个显着好处是序列将被延迟评估。

在这个例子中,我们展示了我们如何首先通过标准阻塞热切评估调用返回一个序列,然后我们展示了返回一个可观察序列而不通过延迟评估阻塞的正确方法。

下面的示例将在他们收到 IObservable 之前被阻止至少 1 秒,无论他们是否确实订阅了它。

private IObservable<string> BlockingMethod()
{
var subject = new ReplaySubject<string>();
subject.OnNext("a");
subject.OnNext("b");
subject.OnCompleted();
Thread.Sleep(1000);
return subject;
}

在 bleow 示例中,消费者立即收到 IObservable,并且只有在订阅时才会产生线程休眠的成本。

private IObservable<string> NonBlocking()
{

return Observable.Create<string>(

(IObserver<string> observer) =>
{

observer.OnNext("a");
observer.OnNext("b");
observer.OnCompleted();
Thread.Sleep(1000);
return Disposable.Create(() => Console.WriteLine("Observer has unsubscribed"));
//or can return an Action like 
//return () => Console.WriteLine("Observer has unsubscribed"); 
});
}
于 2015-06-28T13:10:13.067 回答