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

Woohoo!それはまさに私が探していたものでした!スーパーシンプル(と少し明らかなハハ)を起動します。ありがとう@ Shlomo! –

2

私は行くつもりです必要なクエリのバージョンが少し異なります。

現在、コードのクエリ部分(.Merge()までのビットはコマンドを選択するだけです)を使用して、コマンドを実行するサブスクライバに依存しています。

私が考えているのは、オブザーバブルを購読するときに、サブスクライバが何をしているかにかかわらずコマンドが実行されるようにするということです。観察可能なものに反応して、それが必要と感じたら価値を生み出します。

これはコードです:

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

関連する問題