Subject 类型实现IObservable 和IObserver ,在它既是观察者又是可观察者的意义上。您可以使用主题订阅所有观察者,然后将主题订阅到后端数据源。以这种方式,主体可以充当一组订户和源的代理。你可以使用主题实现一个自定义observable与缓存,缓冲和时间移位。此外,您可以使用主题向多个订阅者广播数据。 默认情况下,主题不通过线程执行任何同步。他们不采取调度程序,而是假定所有序列化和语法正确性由主体的调用者处理。主题简单地广播到线程安全的订户列表中的所有订阅的观察者。这样做具有减少开销和提高性能的优点。但是,如果要使用调度程序将传出调用同步到观察者,则可以使用同步方法执行此操作。
在以下示例中,我们创建一个主题,订阅该主题,然后使用相同的主题向观察者发布值。 通过这样做,我们将发布和订阅组合到同一个源中。 除了获取IObserver ,Subscribe方法还有一个重载,它对onNext采用Action ,这意味着每次发布项目时都会执行该操作。 在我们的示例中,每当OnNext被调用时,该项目将被写入控制台。
Subject<int> subject = new Subject<int>();var subscription = subject.Subscribe( x => Console.WriteLine("Value published: {0}", x), () => Console.WriteLine("Sequence Completed."));subject.OnNext(1);subject.OnNext(2);Console.WriteLine("PRess any key to continue");Console.ReadKey();subject.OnCompleted();subscription.Dispose();以下示例说明了Subject的代理和广播性质。 我们首先创建一个源序列,每1秒产生一个整数。 然后我们创建一个Subject,并将它作为观察者传递给源,以便它将接收由该源序列推出的所有值。 之后,我们创建另外两个订阅,这次以主题为源。 然后,subSubject1和subSubject2订阅将接收Subject发送的任何值(从源)。
var source = Observable.Interval(TimeSpan.FromSeconds(1));Subject<long> subject = new Subject<long>();var subSource = source.Subscribe(subject);var subSubject1 = subject.Subscribe( x => Console.WriteLine("Value published to observer #1: {0}", x), () => Console.WriteLine("Sequence Completed."));var subSubject2 = subject.Subscribe( x => Console.WriteLine("Value published to observer #2: {0}", x), () => Console.WriteLine("Sequence Completed."));Console.WriteLine("Press any key to continue");Console.ReadKey();subject.OnCompleted();subSubject1.Dispose();subSubject2.Dispose();Rx库中的Subject 类型是ISubject 接口的基本实现(您也可以实现ISubject 接口来创建自己的主题类型)。还存在提供不同功能的ISubject 的其他实现。所有这些类型存储通过OnNext推送到它们的一些(或所有)值,并将其广播回其观察者。这样,他们将热观察变为冷观察。这意味着,如果您多次订阅这些内容(即订阅 - >取消订阅 - >再次订阅),您将再次看到至少一个相同的值。有关热观察和冷观察的更多信息,请参阅创建和订阅简单可观察序列主题中的最后一节。 ReplaySubject存储它已发布的所有值。因此,当您订阅它时,您会自动收到已发布的值的完整历史记录,即使您的订阅可能在某些值被推出后才进入。 BehaviourSubject类似于ReplaySubject,除了它只存储它发布的最后一个值。 BehaviourSubject在初始化时还需要类型T的默认值。当主体尚未接收到其他值时,此值将发送给观察者。这意味着所有订阅者都将在订阅时立即收到一个值,除非主题已经完成。 AsyncSubject类似于Replay和Behavior主题,但它将仅存储最后一个值,并且只在序列完成时发布。对于源可观察程序热的情况,可以使用AsyncSubject类型,并且可以在任何观察者订阅之前完成。在这种情况下,AsyncSubject仍然可以提供最后一个值,并将其发布到任何未来的订阅者。
返回列表
新闻热点
疑难解答