使いやすく、外部ライブラリを使用する必要がないシンプルなスケジューラを作成しました。TaskSchedulerは、タイマーの参照を保持するシングルトンであるため、タイマーがガベージコレクションされることはなく、複数のタスクをスケジュールできます。この時刻のスケジュールが超過している場合は、最初の実行(時間と分)を設定して、その時刻の翌日に開始することができます。しかし、コードをカスタマイズするのは簡単です。
新しいタスクのスケジュールはとても簡単です。例:11:52では、最初のタスクは15秒ごとで、2番目の例は5秒ごとです。毎日実行する場合は、24を3パラメーターに設定します。
TaskScheduler.Instance.ScheduleTask(11, 52, 0.00417,
() =>
{
Debug.WriteLine("task1: " + DateTime.Now);
});
TaskScheduler.Instance.ScheduleTask(11, 52, 0.00139,
() =>
{
Debug.WriteLine("task2: " + DateTime.Now);
});
私のデバッグウィンドウ:
task2: 07.06.2017 11:52:00
task1: 07.06.2017 11:52:00
task2: 07.06.2017 11:52:05
task2: 07.06.2017 11:52:10
task1: 07.06.2017 11:52:15
task2: 07.06.2017 11:52:15
task2: 07.06.2017 11:52:20
task2: 07.06.2017 11:52:25
...
このクラスをプロジェクトに追加するだけです。
public class TaskScheduler
{
private static TaskScheduler _instance;
private List<Timer> timers = new List<Timer>();
private TaskScheduler() { }
public static TaskScheduler Instance => _instance ?? (_instance = new TaskScheduler());
public void ScheduleTask(int hour, int min, double intervalInHour, Action task)
{
DateTime now = DateTime.Now;
DateTime firstRun = new DateTime(now.Year, now.Month, now.Day, hour, min, 0, 0);
if (now > firstRun)
{
firstRun = firstRun.AddDays(1);
}
TimeSpan timeToGo = firstRun - now;
if (timeToGo <= TimeSpan.Zero)
{
timeToGo = TimeSpan.Zero;
}
var timer = new Timer(x =>
{
task.Invoke();
}, null, timeToGo, TimeSpan.FromHours(intervalInHour));
timers.Add(timer);
}
}