2012-05-01 4 views
1

스위치와 같은 확장 프로그램을 찾고 있지만 가장 최근의 스트림을 기본값으로 설정하는 대신 다른 외부 이벤트를 기반으로 앞뒤로 이동할 수있는 추가 변수가있는 스위치가 필요합니다.반응 프레임 워크 스트림 전환

예 : 우리는 두 개의 스트림 AB의 병합을 관찰 할 수 있습니다. 이벤트 C이 감지되면, 나는 관측 할 수있는 A을 통과시키고, B의 스트림은 무시 (손실)해야합니다. 이벤트 D이 감지되면 관찰 가능한 A 스트림을 삭제하고 B을 전달해야합니다.

무엇을위한 최고의 linq 연산자가 무엇입니까? 나는 어디에서 어떤 맞춤 솔루션을 사용할 수 있지만 실제로는보다 우아한 솔루션을 찾고 있다고 생각합니다.

또한 가능한 경우 스트림에서 구독/재배포하는 것을 피하고 싶습니다. 나는 구독자/resubscribing이 일반적으로 추적하기가 정말로 어렵고 연산자를 연결하기가 어렵다는 것을 발견했습니다.

+0

이벤트'C'와'D'는'A'와'B' 스트림에서 유추되었거나 외부 이벤트입니까? 그리고'A'와'B'는 같은 타입입니까? – yamen

+0

@yamen 외부 이벤트입니다. – Alwyn

답변

3

여러 가지 방법으로 해결할 수 있습니다. 간단한 것을 살펴 보겠습니다. 이 예제에서는 이벤트가 AB이 같은 유형이라고 가정합니다. 나는 또한 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 % 깨끗합니다.

+0

고맙습니다. 멋진 답변입니다! – Alwyn

+0

빠른 질문 비록 : 전환 관찰의 끝에 Concat()와 함께 무엇입니까? – Alwyn

+1

나는 그것을 훨씬 더 단순하게 편집했다. 'GroupJoin' (그리고 이제는'Window') 함수가 각 윈도우 나 버퍼를 또 다른'IObservable'으로 반환하기 때문에'Concat'이 필요합니다. 그래서 리턴 타입은'IObservable >'입니다. 'Concat'은'IObservable '으로 그것을 평평하게 만듭니다. – yamen

관련 문제