6

毎秒(潜在的に)発火するイベントがあります(タイマーティック)。私がやりたいのは、EventArgs60秒ごとに最後のティックの値を取得することです(それらの60秒の間に新しいティックがあった場合)。私は次のようなことをしてみました:

Observable.FromEventPattern(
    h => myThing.SomeEvent += h,
    h => myThing.SomeEvent -= h)
        .Throttle(TimeSpan.FromSeconds(60))
        .TakeLast(1)
        .Do(p => // do something with p);

残念ながらDo、私はその方法にたどり着くことができず、何が間違っているのかわかりませんか?

これが完全に間違っている場合はお詫びします。初めてRxを使用します:)

編集:以下の提案に従って、に変更DoしましたSubscribeが、を使用しても結果が得られませんThrottle。私はそれを使うべきですか?

4

4 に答える 4

14

私はこれが過剰に設計されていると思います、あなたはただ使う必要がありますSample、それはあなたが望むことを正確に行います:

source.Sample(TimeSpan.FromSeconds(60)).Subscribe(x => /* .. */);
于 2012-07-26T10:44:54.863 に答える
7

これを行う:

Observable.FromEventPattern(h => myThing.SomeEvent += h, h => myThing.SomeEvent -= h)
    .Window(TimeSpan.FromSeconds(60))
    .SelectMany(x => x.TakeLast())
    .Subscribe(x => /* ... */);
于 2012-07-26T09:58:24.873 に答える
3

そのスニペットを考えると、Observableをサブスクライブするまで何も起こりません。IIRC、イベントは誰かがサブスクライブを呼び出したときにのみ接続されます(つまり、サブスクリプションを破棄すると接続されません)。

Doの使用は避けようとしています。observableは値のストリームであり、Subscribe中に渡されたメソッドを介して、これらの値(およびストリームの終了または障害)を実際に処理する必要があります。その後、Doは副作用になります。これは、OnNextメソッドに向かう途中で値が急上昇するときに行うことです。

于 2012-07-25T20:31:23.743 に答える
2

スロットルは問題を解決しません。

スロットルが機能する方法は、指定された時間の間一時停止を待機することです。たとえば、毎秒イベントを取得し、スロットルが1分である場合、何も表示されません。ストリームで何かが発生し、突然1分以上一時停止しない限り、

スロットルの最もよく使用される例の1つは、オートコンプリートボックスに使用することです。この場合、キーストロークごとにフィルターされたリストのリクエストを実行したくないので、たとえば300ミリ秒にスロットルを設定します。これにより、ユーザーが停止するたびに少なくとも300ミリ秒入力すると、検索が開始されます。

代わりに、あなたのソリューションがバッファまたはウィンドウの恩恵を受けるのではないかと思います...ポールは、現時点で私の脳よりもはるかに素晴らしい何かを理解できるに違いありません。ここ数ヶ月Rxをあまり使用していません:(

于 2012-07-26T09:25:36.860 に答える