Search code examples
c#timersystem.reactive

Generate events with dynamically changeable time interval


I have a stream of numeric values that arrive at a fast rate (sub-millisecond), and I want to display their "instant value" on screen, and for usability reasons I should downsample that stream, updating the last value using a configurable time interval. That configuration would be done by user preference, via dragging a slider.

So what I want to do is to store the last value of the source stream in a variable, and have an auto-retriggering timer that updates the displayed value with that variable's value.

I think about using RX, something like this:

Observable.FromEventPattern<double>(_source, "NewValue")
          .Sample(TimeSpan.FromMilliseconds(100))
          .Subscribe(ep => instantVariable = ep.EventArgs)

The problem is that I cannot, as far as I know, dynamically change the interval.

I can imagine there are ways to do it using timers, but I would prefer to use RX.


Solution

  • Assuming you can model the sample-size changes as an observable, you can do this:

    IObservable<int> sampleSizeObservable;
    
    var result = sampleSizeObservable
        .Select(i => Observable.FromEventPattern<double>(_source, "NewValue")
            .Sample(TimeSpan.FromMilliseconds(i))
        )
        .Switch();
    

    Switch basically does what you want, but via Rx. It doesn't "change" the interval: Observables are (generally) supposed to be immutable. Rather whenever the sample size changes, it creates a new sampling observable, subscribes to the new observable, drops the subscription to the old one, and melds those two subscriptions together so it looks seamless to a client subscriber.