2017-11-27 5 views
1

Rx.Net을 배우고 있으며 수많은 간격으로 실행되는 스케줄러를 만들고 있습니다. 개념은 내가 간격의 모음과 명령의 모음을 가지고 있고, 그것들을 하나로 묶고 병합 된 결과에 구독한다는 것이다. 각 명령은 해당 간격과 연관되며 연관과 함께 정의 된 간격 (종지)에 실행됩니다.Observable과 State를 쌍으로 만드는 방법은 무엇입니까?

간격을 병합 할 수 있지만이 명령 (상태)을 구독에 전달하는 방법을 파악하는 데 시간이 많이 걸리고 있습니다. 나는 Scan 함수를 보았지만, 이것은 집계하고 결합/튜플이 아닌 것처럼 보입니다. 여기 내 코드는 다음과 같습니다.

var intervals = new[] 
       { 
        TimeSpan.FromSeconds(30), 
        TimeSpan.FromSeconds(60), 
        TimeSpan.FromSeconds(90) 
       }; 
var commands = new Action[] 
       { 
        () => Console.WriteLine("30 Seconds!"), 
        () => Console.WriteLine("60 Seconds!"), 
        () => Console.WriteLine("90 Seconds!") 
       }; 

intervals.Zip(commands, ValueTuple.Create) 
     .Select(x => Observable.Interval(x.Item1)) // <-- Need magic here. :) 
     .Merge() 
     .Subscribe(x => 
        { 
         x.Item2(); // Broken, x is a long. 
        }); 

여기서 달성하고자하는 방법은 있습니까? Scan과 같지만 누적 기가 아니라 튜플러 (단어 인 경우)입니다.

답변

3

당신이 작업을 30 반복하려는 경우, 60 분, 90 초 간격 :

intervals.Zip(commands, ValueTuple.Create) 
     .Select(x => Observable.Interval(x.Item1).Select(_ => x)) 
     .Merge() 
     .Subscribe(x => 
        { 
         x.Item2(); // Broken, x is a long. 
        }); 

방금 ​​작업 한 번 트리거 할 경우

intervals.Zip(commands, ValueTuple.Create) 
     .Select(x => Observable.Delay(Observable.Return(x), x.Item1)) 
     .Merge() 
     .Subscribe(x => 
        { 
         x.Item2(); // Broken, x is a long. 
       }); 
+0

우후! 그게 바로 제가 찾고 있던 것이 었습니다! 슈퍼 간단한 (그리고 조금 분명 하하) 부팅합니다. 고마워요 @Shlomo! –

2

내가 갈거야 필요한 쿼리의 버전이 약간 다릅니다.

코드의 쿼리 부분 (.Merge()까지의 비트는 명령을 선택하기 만합니다. 사용자는 명령을 실행하기 위해 구독자에 의존하고 있습니다.) 어떤 상황에서는 올바른 논리가 될 수 있지만 전부는 아닐 수도 있습니다.

Observable에 가입하면 가입자가 수행하는 작업과 상관없이 명령이 실행되도록하려는 것입니다. 관측 대상에 반응하여 그것이 필요하다고 느낀다면 가치를 창출하십시오.

여기 코드는

입니다.
IObservable<Unit> query = 
    intervals 
     .Zip(commands, (Interval, Command) => new { Interval, Command }) 
     .Select(x => 
      Observable 
       .Interval(x.Interval) 
       .SelectMany(y => 
        Observable 
         .Start(() => x.Command()))) 
     .Merge(); 

관찰자가 구독 할 때마다 명령이 실행되도록 보장됩니다. 관찰자는 그것이 완료되었다고보고 할 수 있습니다.

가장 기본적인 구독은 이제 IDisposable subscription = query.Subscribe();입니다. 단순한.

+0

Rx에 익숙하지 않고'Observable.Start' (또는 적어도이 맥락에서)에 익숙하지 않았다고 언급 했으므로 이것은 실제로이 문제에 대한 또 다른 귀중한 자료입니다. –

+0

@ Mike-EEE -'Observable.Start'는 코드가 완료 될 때 완료되는 관찰 가능을 생성하는 코드를 실행하는 방법 일뿐입니다. 그것은 TPL을위한'Task.Run'과 같습니다. – Enigmativity