これに取り組む方法はたくさんあります。簡単な方法を見てみましょう。この例では、イベントA
とB
は同じタイプであると想定しています。C
また、イベント(に関連付けられているA
)およびD
(に関連付けられてD
いる)も、重要な情報がなくても観察可能であると想定しています。
var streamA = new Subject<string>();
var streamB = new Subject<string>();
var switchToA = new Subject<Unit>();
var switchToB = new Subject<Unit>();
ここで、火災が発生するstreamA
たびにウィンドウを開き、switchToA
火災が発生するとウィンドウを閉じswitchToB
ます。反対の操作を行ってstreamB
から、それらをマージします。
public IObservable<string> SwitchingWindows(IObservable<string> streamA, IObservable<string> streamB, IObservable<Unit> switchToA, IObservable<Unit> switchToB)
{
var switchedA = streamA.Window(switchToA, _ => switchToB).Concat();
var switchedB = streamB.Window(switchToB, _ => switchToA).Concat();
return switchedA.Merge(switchedB);
}
申し込む:
var all = SwitchingWindows(streamA, streamB, switchToA, switchToB);
all.Subscribe(x => Console.WriteLine(x));
テスト:
streamA.OnNext("a1"); // skip
switchToA.OnNext(Unit.Default); // switch A
streamA.OnNext("a2"); // shown
streamB.OnNext("b1"); // skip
streamA.OnNext("a3"); // shown
switchToB.OnNext(Unit.Default); // switch B
streamB.OnNext("b2"); // shown
streamB.OnNext("b3"); // shown
streamA.OnNext("a4"); // skip
switchToA.OnNext(Unit.Default); // switch A
streamA.OnNext("a5"); // shown
streamB.OnNext("b4"); // skip
streamB.OnNext("b5"); // skip
switchToB.OnNext(Unit.Default); // switch B
streamB.OnNext("b6"); // shown
streamA.OnNext("a6"); // skip
出力は期待どおりです:
a2
a3
b2
b3
a5
b6
最終的なストリームall
は100%クリーンです。