2012-01-06 9 views
2

私はValueChangedイベントを持っています。 Value> 5とそれに続く値< -5との両方が5秒以内に発生した場合にのみRxを使用して購読したいと思います。前提条件付きの2つのイベントがタイムスパンで発生したときに登録します

私は値条件で動作するオブザーバブルを作成することができました。 5秒以内に解雇されたかどうかを確認するにはどうすればよいですか?


IObservable<MyEventArgs> data = Observable.FromEventPattern<... 

var up = data.Where(ev => ev.Value > 0.5).Take(1); 
var down = data.SkipUntil(up).Where(ev => ev.Value < -0.5).Take(1); 

down.Subscribe(ar => { Console.WriteLine("OK"); }); 

[編集]:ここで

は私のコードですより多くの事で : ここでは、予想される結果は、[編集]を enter image description here

をoccure必要があるときに私の入力データを表す画像であると:

なぜ私はこれが欲しいですか? ;-) 私はWP7加速度計を使用して、 'n'秒以内に発生し、少なくとも0.5G(上)と-0.5G(下)を引き起こした上下移動を検出しようとしています

ありがとう、これについてどのように Bartek

答えて

1

「アップ」に基づいており、上記のように割り当てられている「ダウン」、どのように次のコードについて:

var updown=down.Zip(up,(d,u)=> d).Timeout(TimeSpan.FromSeconds(5)).Retry(); 
    updown.Subscribe(ar => { Console.WriteLine("OK"); }); 

私はまだこれをテストしていませんが、多分これを試して価値があります。

+0

私は悪いテストデータを持っていました: - /あなたの解決策は;-)ありがとう – bodziec

+0

なぜTimeoutException ? Retry()のためですか? – bodziec

+0

はい、これはRetry()のために発生し、再試行後はすべてが最初から開始されます。しかし、このソリューションは熱い観測にしか使えません! –

1

data.TimeStamp(anAppropriateSchedulerPerhapsDispatcherSchedulerOrTaskPool) 
    .Buffer(2 /*items*/, /*advance by*/ 1) 
    .Where(x => x[0].Value > 5 && x[1].Value < -5 && 
     x[1].Timestamp - x[0].Timestamp < TimeSpan.FromSeconds(5)); 
    .Subscribe(x => Console.WriteLine("Found it!")); 
+0

私はRxがイベントでもっと楽になると思っていました: - /ありがとう、私にとってはうまくいきます。 – bodziec

+0

私の問題を説明できるイメージを追加しました。私はあなたのソリューションはこれに適用されないと思う。 – bodziec

+0

これは確かに、あなた自身が図書館を持っている家族であれば、あなたの人生を楽にします。上記のコードがあなたの問題を解決すると思います。 – Christoph

0

Joinオペレータはあなたが探しているものです。

図面に基づいて、最初の連続する高い値または低い値から固定期間にしたいと仮定しました。 RisingEdges関数(私が短期間で最善を尽くすことができる最良の名前)は、これらの最初の連続する値に観測可能なソースをフィルタリングします。そこから

<Extension()> 
Public Function RisingEdges(Of T)(source As IObservable(Of T), 
            level As Func(Of T, Boolean) 
           ) As IObservable(Of T) 
    Return source.Select(Function(v) Tuple.Create(v, level(v))) _ 
       .DistinctUntilChanged(Function(vb) vb.Item2) _ 
       .Where(Function(vb) vb.Item2) _ 
       .Select(Function(vb) vb.Item1) 
End Function 

、あなたはこれらのエッジが接近している例を見つけることJoin演算子を使用することができます。

<Extension()> 
Public Function FindClosePeaks(Of T)(source As IObservable(Of T), 
            high As Func(Of T, Boolean), 
            low As Func(Of T, Boolean), 
            windowDuration As TimeSpan 
            ) As IObservable(Of Tuple(Of T, T)) 
    Return Observable.Join(source.RisingEdges(high), 
          source.RisingEdges(low), 
          Function(h) Observable.Timer(windowDuration), 
          Function(l) Observable.Timer(windowDuration), 
          Function(h, l) Tuple.Create(h, l)) 
End Function 

この機能には2つのサブスクリプションがあるので、この関数をコールドオブザーバブルで使用することに注意してください。ソースに応じて、これは受け入れられるかもしれません、またはPublishでそれを "ホット"にする必要があります。

最終結果としてあなたが探していたものは完全にはっきりしていませんでしたが、これはあなたが望むものに近づけるはずです。

関連する問題