Search code examples
c#.netsystem.reactive

Rx .Net TestScheduler- executing immediately scheduled events


When I do this:

testScheduler.Schedule("Hello world",(scheduler, state) => Console.WriteLine(state));
testScheduler.AdvanceTo(testScheduler.Now);

I hit this code in VirtualTimeSchedulerBase:

public void AdvanceTo(TAbsolute time)
{
  int num = this.Comparer.Compare(time, this.Clock);
  if (num < 0)
    throw new ArgumentOutOfRangeException("time");
  if (num == 0)
    return;

num == 0 is true, and I exit the method.

I can call testScheduler.Start() and my action will execute. But then TestScheduler will carry on executing everything in its queue. Whereas I want it to stop executing actions at the current time.

I can't see any other methods on TestScheduler that will get me the behaviour I want.

Is this a bug, or is it the correct behaviour but I'm missing something?

Edit:

I misunderstood. TestScheduler doesn't execute actions until after the date at which they are scheduled.

Scheduling an action immediately schedules it for the current value of testScheduler.Now. So it won't be executed until Now + 1.

  var testScheduler = new TestScheduler();
  var due = new DateTime();
    testScheduler.Schedule("Hello world", due, (scheduler, s) =>
  {
    Console.WriteLine(s);
    return Disposable.Empty;
  });
  testScheduler.AdvanceTo(due.Ticks);
  // Nothing has happened

  testScheduler.AdvanceTo(due.Ticks+1);
  // -> "Hello world"

This still isn't the behaviour I would like, but there you go.


Solution

  • use AdvanceBy(1) to advance the scheduler by 1 tick. The scheduler only executes events when the clock actually advances.

    Different schedulers behave differently when you schedule something for immediate execution. Some of them really do execute it immediately. Some put it in a queue to be executed at the first available opportunity.

    There's not a good way for the TestScheduler to behave in this situation unless the API is modified to let you tell it which way it should behave.