0

I'm a bit stumped because I have a hard time finding any relevant info to my question. I'm very new to System.Reactive, so maybe I'm using it wrong.

I have a number of objects that all call a static method during an event. I want to limit the calls to that method.

public class MyObject
{
    public MyObject ()
    {    
        var observable = Observable.FromEventPattern<SizeChangedEventHandler, SizeChangedEventArgs>
            (handler => SizeChanged += handler, handler => SizeChanged -= handler);
        observable.Throttle (TimeSpan.FromMilliseconds (100));
        observable.Subscribe (x =>
        {
            MethodToCall (this);
        });    
    }

    static void MethodToCall (MyObject obj)
    {
        // Do something.
    }
}

Now, that obviously doesn't work because it only throttles calls from this single object which occur well less often than 100ms. What I think I need is some kind of static Observable that accumulates all calls and then dispatches a call after 100ms. Can anyone give me some pointers?

Update: I implemented it with the help of a Stopwatch, which also seems to do the job. I'm still curious about a Reactive solution though.

private static Stopwatch sw = new Stopwatch();

private static void MethodToCall(MyObjectv)
{
    if (sw.ElapsedMilliseconds < 100 && sw.IsRunning)
    {
        return;
    }

    // Some code here

    if (sw.IsRunning)
    {
        sw.Restart();
    }
    else
    {
        sw.Start();
    }
}
Lennart
  • 9,657
  • 16
  • 68
  • 84
  • You could use a `Queue`, calls to that method are enqueued and every 100ms, the next call is dequeued – Biesi Sep 21 '18 at 09:26
  • See https://stackoverflow.com/questions/4123178/a-way-to-push-buffered-events-in-even-intervals – Shlomo Sep 21 '18 at 14:42
  • observable.Throttle (TimeSpan.FromMilliseconds (100)) .Subscribe (x => { MethodToCall (this); }); – Luis Sep 30 '18 at 17:55

1 Answers1

0

You can use the observable in the MethodToCall method implementation instead:

private static Subject<MyObject> subject = new Subject<MyObject>();
private static IDisposable subscription = subject
    .Throttle (TimeSpan.FromMilliseconds (100))
    .Subscribe(v =>
        {
            // Some code here
        });

private static void MethodToCall(MyObject v)
{
    subject.OnNext(v);
}

Then, the throttling becomes an internal implementation detail of MethodToCall.

Paulo Morgado
  • 14,111
  • 3
  • 31
  • 59