4

I am using System.Timers.Timer to execute an action every 10 secs. This action can also be called by other methods if some special condition arises or through UI. If the action is not called from the timer, I just reset the timer.

The code I am using...

timer = new Timer();
timer.Elapsed += (sender, args) => ExecuteAction();
timer.Interval = 10000;
timer.Enabled = true;

public void ExecuteActionAndResetTimer()
{
    ExecuteAction();

    timer.Stop();
    timer.Start();
}

private void ExecuteAction()
{
    // do the work...
}

The expected result, if 'X' is action called from timer (i.e. ExecuteAction), 'X' is action called from outside timer (i.e. ExecuteActionAndResetTimer) and 'o' is a second:

XooooXoXoXooooXoXooooX

This is working fine. I just want to know that can we do this using reactive extensions?

Thanks.

Yogesh
  • 14,498
  • 6
  • 44
  • 69
  • Related: [Create observable from periodic async request](https://stackoverflow.com/questions/64659387/create-observable-from-periodic-async-request) – Theodor Zoulias Nov 20 '20 at 21:06

1 Answers1

5

Yes, this is quite easily done with Rx.

Here's how:

var subject = new Subject<char>();

var query =
    subject
        .StartWith('X')
        .Select(c =>
            Observable
                .Interval(TimeSpan.FromSeconds(10.0))
                .Select(n => 'X')
                .StartWith(c))
        .Switch();

query.Subscribe(x => Console.Write(x));

Thread.Sleep(5000);
subject.OnNext('Q');
Thread.Sleep(15000);
subject.OnNext('W');

That produces the sequence XQXWXXXX with the final Xs going ad-infinitum.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • If you set the interval to every 2 secs, and shift Q to 9 secs, you will see that only one X is fired before the Q instead of 4. In other words, after one X is fired, another X is not fired until Q is fired. I hope what I am saying makes sense. Upvoted though, as this is pretty close. – Yogesh Jul 24 '17 at 11:24
  • @Yogesh - Yes, you're right. I need to trigger the first firing of the subject. I'll fix it. – Enigmativity Jul 24 '17 at 11:28
  • @Yogesh - Fixed. I just needed to move the `.StartWith('X')` to before the `.Select(...)`. – Enigmativity Jul 24 '17 at 11:30
  • Thanks a lot Enigma. This is spot on. Can you point me to some good indepth but easy to understand guides to reactive (basic to advanced)? The documentation for reactive is not very good. Also the guides/examples I found on the net are not too easy to understand, and also don't show reactive's capability to the fullest. – Yogesh Jul 24 '17 at 11:34
  • 1
    @Yogesh - I agree with you. If I were you I'd install http://www.linqpad.net/. It has a number of Rx samples in there and it's a good scratch pad for writing code. I do most of my coding in there now. Well worth paying for the full licence. – Enigmativity Jul 24 '17 at 11:43
  • 1
    @Yogesh See also http://www.introtorx.com/ and http://rxwiki.wikidot.com/101samples – Peter Bons Jul 26 '17 at 06:55