Skip to main content
Commonmark migration
Source Link

###Follow-up

Follow-up

###Example

Example

###Follow-up

###Example

Follow-up

Example

added follow-up link
Source Link
t3chb0t
  • 44.3k
  • 9
  • 84
  • 190

###Follow-up

There is a newer version of the Scheduler.


The Scheduler class is really simple. It's backed by a newer implementation of my old CronExpression.

The Scheduler class is really simple. It's backed by a newer implementation of my old CronExpression.

###Follow-up

There is a newer version of the Scheduler.


The Scheduler class is really simple. It's backed by a newer implementation of my old CronExpression.

Source Link
t3chb0t
  • 44.3k
  • 9
  • 84
  • 190

Scheduler built with observables

I sometimes have to schedule some tasks and wanted to have my own reusable scheduler. Since I like the Rx, I build it on top of it.


The Scheduler class is really simple. It's backed by a newer implementation of my old CronExpression.

There are currently only these two methods. The factory method Create creates a new scheduler that ticks at the specified intervals and provides schedules as DateTimes to the observers.

Jobs are scheduled with the Schedule extension. This one requires a cron-expression and the action to execute.

public static class Scheduler
{
    public static IObservable<DateTime> Create(TimeSpan interval, IDateTime dateTime)
    {
        return
            Observable
                .Interval(TimeSpan.FromSeconds(1))
                .Select(_ => dateTime.Now());
    }

    public static IDisposable Schedule(this IObservable<DateTime> schedules, string cronExpressionString, Action<DateTime> action)
    {
        var cronExpression = CronExpression.Parse(cronExpressionString);
        return
            schedules
                .Where(cronExpression.Contains)
                .Subscribe(action);
    }
}

The DateTime abstraction is supported by the IDateTime interface:

public interface IDateTime
{
    DateTime Now();
}

which is implemented as

public class LocalDateTime : IDateTime
{
    public DateTime Now() => DateTime.Now;
}

or

public class UtcDateTime : IDateTime
{
    public DateTime Now() => DateTime.UtcNow;
}

###Example

In order to use it I just create a scheduler, specify what kind of timestamp it should generate and schedule some actions:

var scheduler = Scheduler.Create(TimeSpan.FromSeconds(1), new LocalDateTime());

scheduler.Schedule("0/1 * * * * * *", schedule =>
{
    Console.WriteLine($"DEBUG: {schedule} [{Thread.CurrentThread.ManagedThreadId}]");
});

scheduler.Schedule("0/5 * * * * * *", schedule =>
{
    Console.WriteLine($"ACTION: {schedule}");
});

The output is:

DEBUG: 13/04/2018 22:32:09 [10]
DEBUG: 13/04/2018 22:32:10 [12]
ACTION: 13/04/2018 22:32:10
DEBUG: 13/04/2018 22:32:11 [10]
DEBUG: 13/04/2018 22:32:12 [14]
DEBUG: 13/04/2018 22:32:13 [8]
DEBUG: 13/04/2018 22:32:14 [12]
ACTION: 13/04/2018 22:32:15
DEBUG: 13/04/2018 22:32:15 [8]
DEBUG: 13/04/2018 22:32:16 [12]
DEBUG: 13/04/2018 22:32:17 [8]

There seems to be no rocket science here but this might elusive. Can/should this scheduler by improved in any way?