简体   繁体   English

Rx如何从pub / sub模式创建序列

[英]Rx how to create a sequence from a pub/sub pattern

I'm trying to evaluate using Rx to create a sequence from a pub/sub pattern (ie classic observer pattern where next element is published by the producer(s)). 我正在尝试使用Rx来评估从发布/子模式创建序列(即经典观察者模式,其中下一个元素由生产者发布)。 This is basically the same as .net events, except we need to generalize it such that having an event is not a requirement, so I'm not able to take advantage of Observable.FromEvent. 这基本上与.net事件相同,除了我们需要概括它以使得事件不是必需的,所以我无法利用Observable.FromEvent。 I've played around with Observable.Create and Observable.Generate and find myself end up having to write code to take care of the pub/sub (ie I have to write producer/consumer code to stash the published item, then consume it by calling IObserver.OnNext() with it), so it seems like I'm not really taking advantage of Rx... 我玩过Observable.Create和Observable.Generate并发现自己最终不得不编写代码来处理pub / sub(即我必须编写生产者/消费者代码来存储已发布的项目,然后通过用它来调用IObserver.OnNext()),所以看起来我并没有真正利用Rx ......

Am I looking down the correct path or is this a good fit for Rx? 我是在寻找正确的路径还是适合Rx?

Thanks 谢谢

Your publisher just exposes some IObservables as properties. 您的发布者只是将一些IObservables暴露为属性。 And your consumers just Subscribe to them (or do any Rx-fu they want before subscribing). 而且您的消费者只需Subscribe它们(或者在订阅之前做任何他们想要的Rx-fu)。

Sometimes this is as simple as using Subjects in your publisher. 有时这就像在您的出版商中使用Subjects一样简单。 And sometimes it is more complex because your publisher is actually observing some other observable process. 有时它更复杂,因为您的发布者实际上正在观察其他一些可观察的过程。

Here is a dumb example: 这是一个愚蠢的例子:

public class Publisher
{
    private readonly Subject<Foo> _topic1;

    /// <summary>Observe Foo values on this topic</summary>
    public IObservable<Foo> FooTopic
    {
       get { return _topic1.AsObservable(); }
    }

    private readonly IObservable<long> _topic2;

    /// <summary>Observe the current time whenever our clock ticks</summary>
    public IObservable<DateTime> ClockTickTopic
    {
        get { return _topic2.Select(t => DateTime.Now); }
    }

    public Publisher()
    {
         _topic1 = new Subject<Foo>();
         // tick once each second
         _topic2 = Observable.Interval(TimeSpan.FromSeconds(1));
    }

    /// <summary>Let everyone know about the new Foo</summary>
    public NewFoo(Foo foo) { _topic1.OnNext(foo); }
}


// interested code...
Publisher p = ...;
p.FooTopic.Subscribe(foo => ...);

p.ClickTickTopic.Subscribe(currentTime => ...);

// count how many foos occur during each clock tick
p.FooTopic.Buffer(p.ClockTickTopic)
    .Subscribe(foos => Console.WriteLine("{0} foos during this interval", foos.Count));

Using RX is definitely a good fit for pub/sub. 使用RX绝对适合pub / sub。 Here is a demo that illustrates the simplest possible pub/sub pattern using IObservable and RX. 这是一个演示,演示了使用IObservable和RX的最简单的发布/子模式。

Add Reactive Extensions (RX) to your project using NuGet, search for rx-main and install Reactive Extensions - Main Library . 使用NuGet将Reactive Extensions(RX)添加到项目中,搜索rx-main并安装Reactive Extensions - Main Library

using System;
using System.Reactive.Subjects;

namespace RX_2
{
    public static class Program
    {
        static void Main(string[] args)
        {
            Subject<int> stream = new Subject<int>();

            stream.Subscribe(
                o =>
                {
                    Console.Write(o);
                });

            stream.Subscribe(
                o =>
                {
                    Console.Write(o);
                });

            for (int i = 0; i < 5; i++)
            {
                stream.OnNext(i);
            }

            Console.ReadKey();
        }
    }
}

When executed, the code outputs this: 执行时,代码输出:

0011223344

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM