我正在编写一个有效地与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;
});
}