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 DateTime
s 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?