Switch vs SelectMany + TakeUntil

时间:2015-04-08 07:47:48

标签: system.reactive

我正在编写一个有效地与Switch相同的运算符以及其他一些东西。我总是理解Switch有效地成为SelectMany与TakeUntil相结合的整洁包装器。然而,在实现我的新扩展时,我注意到有关内部序列的创建/处理顺序的不同之处。我想知道如何复制Switch工作的顺序,因为我们似乎总是想在创建一个新内部之前处理现有的内部。

我写了2个测试来说明我的意思。

StandardSwitch将提供以下输出: 处理内部,然后创建新的内部

HandCrankedSwitch将给出: 创造新的内心, 处置内部

请参阅下面的示例代码:

[TestMethod]
    public void StandardSwitch()
    {
        var outer = Observable.Interval(TimeSpan.FromSeconds(1))
            .Do(x => Console.WriteLine("New Outer Value is {0}", x));

        var wait = new CountdownEvent(8);

        outer
            .Select(CreateInner)
            .Switch()
            .Subscribe(x =>
            {
                Console.WriteLine("Subscriber Got {0}", x);
                wait.Signal();
            });

        wait.Wait();

        Console.WriteLine("Done");
    }

[TestMethod]
    public void HandCrankedSwitch()
    {
        var outer = Observable.Interval(TimeSpan.FromSeconds(1))
            .Do(x => Console.WriteLine("New Outer Value is {0}", x));

        var wait = new CountdownEvent(8);

        outer.Publish(x => x.Select(CreateInner).SelectMany(xs => xs.TakeUntil(x)))
            .Subscribe(x =>
            {
                Console.WriteLine("Subscriber Got {0}", x);
                wait.Signal();
            });

        wait.Wait();

        Console.WriteLine("Done");
    }
internal IObservable<long> CreateInner(long notUsed)
    {
        return Observable.Create<long>(obs =>
        {
            Console.WriteLine("Creating New Inner");

            var compDis = new CompositeDisposable {Disposable.Create(() => Console.WriteLine("Disposing Inner"))};

            var dis = Observable.Interval(TimeSpan.FromSeconds(0.4))
                .Do(x => Console.WriteLine("New Inner Value is {0}", x))
                .Subscribe(obs);

            compDis.Add(dis);

            return compDis;
        });
    }

0 个答案:

没有答案