Я строю службу Windows, и я хочу, чтобы она обрабатывала множество различных фоновых задач с настраиваемыми интервалами.Как рассчитать интервалы таймера для ежемесячного планирования?
Мне сложно определить, как вычислить продолжительность времени, в течение которого таймер должен ждать, прежде чем начать какую-либо задачу.
Я хранить StartDate
против задачи и интервального типа: ежедневно, еженедельно, ежемесячно и т.д. Я прибил ежедневно, но не может работать, как сделать ежемесячно ...
Правила, являются:
StartDate
Если в будущем, а затем ждать промежуток времени междуNow
иStartDate
.Если
StartDate
в прошлом, тогда запустите задачу в тот же день месяца/времени, что иStartDate
, но в текущем/следующем месяце. Так что еслиStartDate
- 15 марта в 09:00, а сегодня - 25 мая, то в следующий раз задача должна быть запущена 15 июня в 09:00.
У меня есть до сих пор с этим. Вот тест приложение, которое принимает ряд тестов и пытается вычислить количество часов между текущим временем (согласно тесту) и фиксированное время начала выполнения задачи:
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main() {
// Test cases
var times = new Dictionary<DateTime,TimeSpan> {
{ new DateTime(2016, 3, 1, 9, 0, 0), TimeSpan.FromHours(2016)},
{ new DateTime(2016, 3, 5, 3, 0, 0), TimeSpan.FromHours(1926)},
{ new DateTime(2016, 3, 5, 9, 0, 0), TimeSpan.FromHours(1920)},
{ new DateTime(2016, 3, 5, 15, 0, 0), TimeSpan.FromHours(1914)},
{ new DateTime(2016, 3, 24, 3, 0, 0), TimeSpan.FromHours(1470)},
{ new DateTime(2016, 3, 24, 9, 0, 0), TimeSpan.FromHours(1464)},
{ new DateTime(2016, 3, 24, 15, 0, 0), TimeSpan.FromHours(1458)},
{ new DateTime(2016, 4, 19, 9, 0, 0), TimeSpan.FromHours(840)},
{ new DateTime(2016, 4, 24, 3, 0, 0), TimeSpan.FromHours(726)},
{ new DateTime(2016, 4, 24, 9, 0, 0), TimeSpan.FromHours(720)},
{ new DateTime(2016, 4, 24, 15, 0, 0), TimeSpan.FromHours(714)},
{ new DateTime(2016, 4, 24, 21, 0, 0), TimeSpan.FromHours(708)},
{ new DateTime(2016, 5, 6, 3, 0, 0), TimeSpan.FromHours(438)},
{ new DateTime(2016, 5, 24, 3, 0, 0), TimeSpan.FromHours(6)},
{ new DateTime(2016, 5, 24, 9, 0, 0), TimeSpan.FromHours(0)},
{ new DateTime(2016, 5, 24, 15, 0, 0), TimeSpan.FromHours(738)},
{ new DateTime(2016, 5, 26, 3, 0, 0), TimeSpan.FromHours(702)},
{ new DateTime(2016, 5, 26, 9, 0, 0), TimeSpan.FromHours(696)},
{ new DateTime(2016, 5, 26, 15, 0, 0), TimeSpan.FromHours(690)},
{ new DateTime(2016, 6, 24, 3, 0, 0), TimeSpan.FromHours(6)},
{ new DateTime(2016, 6, 24, 9, 0, 0), TimeSpan.FromHours(0)},
{ new DateTime(2016, 6, 24, 15, 0, 0), TimeSpan.FromHours(714)},
{ new DateTime(2016, 7, 6, 3, 0, 0), TimeSpan.FromHours(438)},
{ new DateTime(2016, 7, 6, 9, 0, 0), TimeSpan.FromHours(432)},
{ new DateTime(2016, 7, 6, 15, 0, 0), TimeSpan.FromHours(426)},
{ new DateTime(2016, 7, 24, 3, 0, 0), TimeSpan.FromHours(6)},
{ new DateTime(2016, 7, 24, 9, 0, 0), TimeSpan.FromHours(0)},
{ new DateTime(2016, 7, 24, 15, 0, 0), TimeSpan.FromHours(738)},
};
var startTime = new DateTime(2016, 05, 24, 09, 00, 00);
var last = times.First().Key;
foreach (var time in times) {
var now = time.Key;
var expected = time.Value;
var timer = startTime.TimeOfDay - now.TimeOfDay;
if (now <= startTime)
timer += TimeSpan.FromDays((startTime.Date - now.Date).TotalDays);
else
timer += TimeSpan.FromDays((now.Date.AddMonths(1) - now.Date).TotalDays);
if (last.Date != now.Date) Console.WriteLine();
Console.WriteLine($"{now:yyyy-MM-dd HH:mm} -> {startTime:yyyy-MM-dd HH:mm} = {timer:dd\\.hh} {(timer != expected ? "EXPECTED " + expected.ToString("dd\\.hh") : "CORRECT ")}");
last = now;
}
}
}
Который производит следующий результат:
2016-03-01 09:00 -> 2016-05-24 09:00 = 84.00 CORRECT
2016-03-05 03:00 -> 2016-05-24 09:00 = 80.06 CORRECT
2016-03-05 09:00 -> 2016-05-24 09:00 = 80.00 CORRECT
2016-03-05 15:00 -> 2016-05-24 09:00 = 79.18 CORRECT
2016-03-24 03:00 -> 2016-05-24 09:00 = 61.06 CORRECT
2016-03-24 09:00 -> 2016-05-24 09:00 = 61.00 CORRECT
2016-03-24 15:00 -> 2016-05-24 09:00 = 60.18 CORRECT
2016-04-19 09:00 -> 2016-05-24 09:00 = 35.00 CORRECT
2016-04-24 03:00 -> 2016-05-24 09:00 = 30.06 CORRECT
2016-04-24 09:00 -> 2016-05-24 09:00 = 30.00 CORRECT
2016-04-24 15:00 -> 2016-05-24 09:00 = 29.18 CORRECT
2016-04-24 21:00 -> 2016-05-24 09:00 = 29.12 CORRECT
2016-05-06 03:00 -> 2016-05-24 09:00 = 18.06 CORRECT
2016-05-24 03:00 -> 2016-05-24 09:00 = 00.06 CORRECT
2016-05-24 09:00 -> 2016-05-24 09:00 = 00.00 CORRECT
2016-05-24 15:00 -> 2016-05-24 09:00 = 30.18 CORRECT
2016-05-26 03:00 -> 2016-05-24 09:00 = 31.06 EXPECTED 29.06
2016-05-26 09:00 -> 2016-05-24 09:00 = 31.00 EXPECTED 29.00
2016-05-26 15:00 -> 2016-05-24 09:00 = 30.18 EXPECTED 28.18
2016-06-24 03:00 -> 2016-05-24 09:00 = 30.06 EXPECTED 00.06
2016-06-24 09:00 -> 2016-05-24 09:00 = 30.00 EXPECTED 00.00
2016-06-24 15:00 -> 2016-05-24 09:00 = 29.18 CORRECT
2016-07-06 03:00 -> 2016-05-24 09:00 = 31.06 EXPECTED 18.06
2016-07-06 09:00 -> 2016-05-24 09:00 = 31.00 EXPECTED 18.00
2016-07-06 15:00 -> 2016-05-24 09:00 = 30.18 EXPECTED 17.18
2016-07-24 03:00 -> 2016-05-24 09:00 = 31.06 EXPECTED 00.06
2016-07-24 09:00 -> 2016-05-24 09:00 = 31.00 EXPECTED 00.00
2016-07-24 15:00 -> 2016-05-24 09:00 = 30.18 CORRECT
Как вы можете видеть, это немного неверно к концу. Каковы расчеты, необходимые для правильного определения количества часов?
не является 'TimeSpan.FromDays ((а - б) .TotalDays)' эквивалент '(а-б) '? –
@IanMercer: Наверное ... Я пробовал много всего, и просто я играл с вычислениями, не пытаясь окончательно его оптимизировать :) – BG100