Skip to main content
deleted 671 characters in body
Source Link
user73941
user73941

Xiaoy312 has a point about the risk of missing seconds when using Interval. It seems that each "tick" of Observable.Interval() waits until the previous returns. So if the OnNext halts the thread a while, the next "tick" is fired too late and you may miss a second or two.

Trying to start each scheduled task on a new thread - for instance via a System.Timers.Timer seems to be a bad idea, since the same Cron job probably can not run concurrently(?).

One way not to lose any seconds using Observable.Interval is as follows:

  Random rand = new Random(5);
  IObservable<Timestamped<long>> source = Observable.Interval(TimeSpan.FromSeconds(1)).Timestamp().ObserveOn(NewThreadScheduler.Default);

  IDisposable subscription = source.Subscribe(
      x =>
      {
        Console.WriteLine("OnNext: {0}", x);
        Thread.Sleep(rand.Next(0, 4001));
        Console.WriteLine("After Sleep OnNext: {0}", x);
      },
      ex => Console.WriteLine("OnError: {0}", ex.Message),
      () => Console.WriteLine("OnCompleted"));


  Console.WriteLine("Press ENTER to unsubscribe...");
  Console.ReadLine();
  subscription.Dispose();

This seems to ensure no slip in the sequence of timestamps (Second-wise at least), but each elapsed interval may be (cumulatively) delayed according to previous intervals "laziness". In this way you are not guarantied that the job is done on schedule, but you won't miss a job because of "missing" seconds. It seems though that the time pump catches up the delay when no action delay the current elapsed interval.


Update

The above solution doesn't solve the millisecond alignment problem described by Xiaoy312.

I think a simple way to solve that could be at simple as this:

public static IObservable<DateTime> Create(TimeSpan interval, DateTime dateTime)
{
  return
      Observable
          .Interval(TimeSpan.FromSeconds(1))
          .Select(_ =>
          {
            DateTime now = DateTime.Now;
            return new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, 0);
          });
}

This should of cause be implemented in the appropriate IDateTime implementation.

Xiaoy312 has a point about the risk of missing seconds when using Interval. It seems that each "tick" of Observable.Interval() waits until the previous returns. So if the OnNext halts the thread a while, the next "tick" is fired too late and you may miss a second or two.

Trying to start each scheduled task on a new thread - for instance via a System.Timers.Timer seems to be a bad idea, since the same Cron job probably can not run concurrently(?).

One way not to lose any seconds using Observable.Interval is as follows:

  Random rand = new Random(5);
  IObservable<Timestamped<long>> source = Observable.Interval(TimeSpan.FromSeconds(1)).Timestamp().ObserveOn(NewThreadScheduler.Default);

  IDisposable subscription = source.Subscribe(
      x =>
      {
        Console.WriteLine("OnNext: {0}", x);
        Thread.Sleep(rand.Next(0, 4001));
        Console.WriteLine("After Sleep OnNext: {0}", x);
      },
      ex => Console.WriteLine("OnError: {0}", ex.Message),
      () => Console.WriteLine("OnCompleted"));


  Console.WriteLine("Press ENTER to unsubscribe...");
  Console.ReadLine();
  subscription.Dispose();

This seems to ensure no slip in the sequence of timestamps (Second-wise at least), but each elapsed interval may be (cumulatively) delayed according to previous intervals "laziness". In this way you are not guarantied that the job is done on schedule, but you won't miss a job because of "missing" seconds. It seems though that the time pump catches up the delay when no action delay the current elapsed interval.


Update

The above solution doesn't solve the millisecond alignment problem described by Xiaoy312.

I think a simple way to solve that could be at simple as this:

public static IObservable<DateTime> Create(TimeSpan interval, DateTime dateTime)
{
  return
      Observable
          .Interval(TimeSpan.FromSeconds(1))
          .Select(_ =>
          {
            DateTime now = DateTime.Now;
            return new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, 0);
          });
}

This should of cause be implemented in the appropriate IDateTime implementation.

Xiaoy312 has a point about the risk of missing seconds when using Interval. It seems that each "tick" of Observable.Interval() waits until the previous returns. So if the OnNext halts the thread a while, the next "tick" is fired too late and you may miss a second or two.

Trying to start each scheduled task on a new thread - for instance via a System.Timers.Timer seems to be a bad idea, since the same Cron job probably can not run concurrently(?).

One way not to lose any seconds using Observable.Interval is as follows:

  Random rand = new Random(5);
  IObservable<Timestamped<long>> source = Observable.Interval(TimeSpan.FromSeconds(1)).Timestamp().ObserveOn(NewThreadScheduler.Default);

  IDisposable subscription = source.Subscribe(
      x =>
      {
        Console.WriteLine("OnNext: {0}", x);
        Thread.Sleep(rand.Next(0, 4001));
        Console.WriteLine("After Sleep OnNext: {0}", x);
      },
      ex => Console.WriteLine("OnError: {0}", ex.Message),
      () => Console.WriteLine("OnCompleted"));


  Console.WriteLine("Press ENTER to unsubscribe...");
  Console.ReadLine();
  subscription.Dispose();

This seems to ensure no slip in the sequence of timestamps (Second-wise at least), but each elapsed interval may be (cumulatively) delayed according to previous intervals "laziness". In this way you are not guarantied that the job is done on schedule, but you won't miss a job because of "missing" seconds. It seems though that the time pump catches up the delay when no action delay the current elapsed interval.

added 675 characters in body
Source Link
user73941
user73941

Xiaoy312 has a point about the risk of missing seconds when using Interval. It seems that each "tick" of Observable.Interval() waits until the previous returns. So if the OnNext halts the thread a while, the next "tick" is fired too late and you may miss a second or two.

Trying to start each scheduled task on a new thread - for instance via a System.Timers.Timer seems to be a bad idea, since the same Cron job probably can not run concurrently(?).

One way not to lose any seconds using Observable.Interval is as follows:

  Random rand = new Random(5);
  IObservable<Timestamped<long>> source = Observable.Interval(TimeSpan.FromSeconds(1)).Timestamp().ObserveOn(NewThreadScheduler.Default);

  IDisposable subscription = source.Subscribe(
      x =>
      {
        Console.WriteLine("OnNext: {0}", x);
        Thread.Sleep(rand.Next(0, 4001));
        Console.WriteLine("After Sleep OnNext: {0}", x);
      },
      ex => Console.WriteLine("OnError: {0}", ex.Message),
      () => Console.WriteLine("OnCompleted"));


  Console.WriteLine("Press ENTER to unsubscribe...");
  Console.ReadLine();
  subscription.Dispose();

This seems to ensure no slip in the sequence of timestamps (Second-wise at least), but each elapsed interval may be (cumulatively) delayed according to previous intervals "laziness". In this way you are not guarantied that the job is done on schedule, but you won't miss a job because of "missing" seconds. It seems though that the time pump catches up the delay when no action delay the current elapsed interval.


Update

The above solution doesn't solve the millisecond alignment problem described by Xiaoy312.

I think a simple way to solve that could be at simple as this:

public static IObservable<DateTime> Create(TimeSpan interval, DateTime dateTime)
{
  return
      Observable
          .Interval(TimeSpan.FromSeconds(1))
          .Select(_ =>
          {
            DateTime now = DateTime.Now;
            return new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, 0);
          });
}

This should of cause be implemented in the appropriate IDateTime implementation.

Xiaoy312 has a point about the risk of missing seconds when using Interval. It seems that each "tick" of Observable.Interval() waits until the previous returns. So if the OnNext halts the thread a while, the next "tick" is fired too late and you may miss a second or two.

Trying to start each scheduled task on a new thread - for instance via a System.Timers.Timer seems to be a bad idea, since the same Cron job probably can not run concurrently(?).

One way not to lose any seconds using Observable.Interval is as follows:

  Random rand = new Random(5);
  IObservable<Timestamped<long>> source = Observable.Interval(TimeSpan.FromSeconds(1)).Timestamp().ObserveOn(NewThreadScheduler.Default);

  IDisposable subscription = source.Subscribe(
      x =>
      {
        Console.WriteLine("OnNext: {0}", x);
        Thread.Sleep(rand.Next(0, 4001));
        Console.WriteLine("After Sleep OnNext: {0}", x);
      },
      ex => Console.WriteLine("OnError: {0}", ex.Message),
      () => Console.WriteLine("OnCompleted"));


  Console.WriteLine("Press ENTER to unsubscribe...");
  Console.ReadLine();
  subscription.Dispose();

This seems to ensure no slip in the sequence of timestamps (Second-wise at least), but each elapsed interval may be (cumulatively) delayed according to previous intervals "laziness". In this way you are not guarantied that the job is done on schedule, but you won't miss a job because of "missing" seconds. It seems though that the time pump catches up the delay when no action delay the current elapsed interval.

Xiaoy312 has a point about the risk of missing seconds when using Interval. It seems that each "tick" of Observable.Interval() waits until the previous returns. So if the OnNext halts the thread a while, the next "tick" is fired too late and you may miss a second or two.

Trying to start each scheduled task on a new thread - for instance via a System.Timers.Timer seems to be a bad idea, since the same Cron job probably can not run concurrently(?).

One way not to lose any seconds using Observable.Interval is as follows:

  Random rand = new Random(5);
  IObservable<Timestamped<long>> source = Observable.Interval(TimeSpan.FromSeconds(1)).Timestamp().ObserveOn(NewThreadScheduler.Default);

  IDisposable subscription = source.Subscribe(
      x =>
      {
        Console.WriteLine("OnNext: {0}", x);
        Thread.Sleep(rand.Next(0, 4001));
        Console.WriteLine("After Sleep OnNext: {0}", x);
      },
      ex => Console.WriteLine("OnError: {0}", ex.Message),
      () => Console.WriteLine("OnCompleted"));


  Console.WriteLine("Press ENTER to unsubscribe...");
  Console.ReadLine();
  subscription.Dispose();

This seems to ensure no slip in the sequence of timestamps (Second-wise at least), but each elapsed interval may be (cumulatively) delayed according to previous intervals "laziness". In this way you are not guarantied that the job is done on schedule, but you won't miss a job because of "missing" seconds. It seems though that the time pump catches up the delay when no action delay the current elapsed interval.


Update

The above solution doesn't solve the millisecond alignment problem described by Xiaoy312.

I think a simple way to solve that could be at simple as this:

public static IObservable<DateTime> Create(TimeSpan interval, DateTime dateTime)
{
  return
      Observable
          .Interval(TimeSpan.FromSeconds(1))
          .Select(_ =>
          {
            DateTime now = DateTime.Now;
            return new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, 0);
          });
}

This should of cause be implemented in the appropriate IDateTime implementation.

added 107 characters in body
Source Link
user73941
user73941

Xiaoy312 has a point about the risk of missing seconds when using Interval. It seems that each "tick" of Observable.Interval() waits until the previous returns. So if the OnNext halts the thread a while, the next "tick" is fired too late and you may miss a second or two.

Trying to start each scheduled task on a new thread - for instance via a System.Timers.Timer seems to be a bad idea, since the same Cron job probably can not run concurrently(?).

One way not to lose any seconds using Observable.Interval is as follows:

  Random rand = new Random(5);
  IObservable<Timestamped<long>> source = Observable.Interval(TimeSpan.FromSeconds(1)).Timestamp().ObserveOn(NewThreadScheduler.Default);

  IDisposable subscription = source.Subscribe(
      x =>
      {
        Console.WriteLine("OnNext: {0}", x);
        Thread.Sleep(rand.Next(0, 4001));
        Console.WriteLine("After Sleep OnNext: {0}", x);
      },
      ex => Console.WriteLine("OnError: {0}", ex.Message),
      () => Console.WriteLine("OnCompleted"));


  Console.WriteLine("Press ENTER to unsubscribe...");
  Console.ReadLine();
  subscription.Dispose();

This seems to ensure no slip in the sequence of timestamps (Second-wise at least), but each elapsed interval may be (cumulatively) delayed according to previous intervals "laziness". In this way you are not guarantied that the job is done on schedule, but you won't miss a job because of "missing" seconds. It seems though that the time pump catches up the delay when no action delay the current elapsed interval.

Xiaoy312 has a point about the risk of missing seconds when using Interval. It seems that each "tick" of Observable.Interval() waits until the previous returns. So if the OnNext halts the thread a while, the next "tick" is fired too late and you may miss a second or two.

Trying to start each scheduled task on a new thread - for instance via a System.Timers.Timer seems to be a bad idea, since the same Cron job probably can not run concurrently(?).

One way not to lose any seconds using Observable.Interval is as follows:

  Random rand = new Random(5);
  IObservable<Timestamped<long>> source = Observable.Interval(TimeSpan.FromSeconds(1)).Timestamp().ObserveOn(NewThreadScheduler.Default);

  IDisposable subscription = source.Subscribe(
      x =>
      {
        Console.WriteLine("OnNext: {0}", x);
        Thread.Sleep(rand.Next(0, 4001));
        Console.WriteLine("After Sleep OnNext: {0}", x);
      },
      ex => Console.WriteLine("OnError: {0}", ex.Message),
      () => Console.WriteLine("OnCompleted"));


  Console.WriteLine("Press ENTER to unsubscribe...");
  Console.ReadLine();
  subscription.Dispose();

This seems to ensure no slip in the sequence of timestamps (Second-wise at least), but each elapsed interval may be (cumulatively) delayed according to previous intervals "laziness". In this way you are not guarantied that the job is done on schedule, but you won't miss a job because of "missing" seconds.

Xiaoy312 has a point about the risk of missing seconds when using Interval. It seems that each "tick" of Observable.Interval() waits until the previous returns. So if the OnNext halts the thread a while, the next "tick" is fired too late and you may miss a second or two.

Trying to start each scheduled task on a new thread - for instance via a System.Timers.Timer seems to be a bad idea, since the same Cron job probably can not run concurrently(?).

One way not to lose any seconds using Observable.Interval is as follows:

  Random rand = new Random(5);
  IObservable<Timestamped<long>> source = Observable.Interval(TimeSpan.FromSeconds(1)).Timestamp().ObserveOn(NewThreadScheduler.Default);

  IDisposable subscription = source.Subscribe(
      x =>
      {
        Console.WriteLine("OnNext: {0}", x);
        Thread.Sleep(rand.Next(0, 4001));
        Console.WriteLine("After Sleep OnNext: {0}", x);
      },
      ex => Console.WriteLine("OnError: {0}", ex.Message),
      () => Console.WriteLine("OnCompleted"));


  Console.WriteLine("Press ENTER to unsubscribe...");
  Console.ReadLine();
  subscription.Dispose();

This seems to ensure no slip in the sequence of timestamps (Second-wise at least), but each elapsed interval may be (cumulatively) delayed according to previous intervals "laziness". In this way you are not guarantied that the job is done on schedule, but you won't miss a job because of "missing" seconds. It seems though that the time pump catches up the delay when no action delay the current elapsed interval.

Source Link
user73941
user73941
Loading