title: Cron Observable Sequence
body: <p>I would like to create an observable sequence using reactive extensions (RX) and NCrontab. The sequence would differ from something like <code>Observable.Timer()</code> in that the period and due time are not fixed. After reading <a href="http://www.introtorx.com/content/v1.0.10621.0/04_CreatingObservableSequences.html" rel="nofollow">this article</a> it seems that <code>Observable.Generate()</code> is the way to go. I am thinking of two variants: one which runs within bounds and one that runs forever. Do these implementation make sense? </p>
  
  <pre><code>public static IObservable&lt;DateTime&gt; Cron(string cron)
  {
      var schedule = CrontabSchedule.Parse(cron);
      return Observable.Generate(DateTime.Now, d=&gt;true, d =&gt; DateTime.Now, d =&gt; d,
          d =&gt; new DateTimeOffset(schedule.GetNextOccurrence(d)));
  }
  
  public static IObservable&lt;DateTime&gt; Cron(string cron, DateTime start, DateTime end)
  {
      var schedule = CrontabSchedule.Parse(cron);
      return Observable.Generate(start, d =&gt; d &lt; end, d =&gt; DateTime.Now, d =&gt; d,
          d =&gt; new DateTimeOffset(schedule.GetNextOccurrence(d)));
  }
  </code></pre>
  
  <p><em>update</em>: These seem to work empirically, however I added an overload which takes an <code>IScheduler</code> and cannot seem to get the sequence to trigger in a unit test. Am I using <code>TestScheduler</code> wrong or is there an issue with the function implementation?</p>
  
  <pre><code>public static IObservable&lt;int&gt; Cron(string cron, IScheduler scheduler)
  {
      var schedule = CrontabSchedule.Parse(cron);
      return Observable.Generate(0, d =&gt; true, d =&gt; d + 1, d =&gt; d,
          d =&gt; new DateTimeOffset(schedule.GetNextOccurrence(scheduler.Now.DateTime)), scheduler);
  }
  
  [TestClass]
  public class EngineTests
  {
      [TestMethod]
      public void TestCron()
      {
          var scheduler = new TestScheduler();
          var cron = "* * * * *";
          var values = new List&lt;int&gt;();
          var disp = ObservableCron.Cron(cron, scheduler).Subscribe(values.Add);
          scheduler.AdvanceBy(TimeSpan.TicksPerMinute - 1);
          scheduler.AdvanceBy(1);
          scheduler.AdvanceBy(1);
          Assert.IsTrue(values.Count&gt; 0);
      }
  }
  </code></pre>