Я пытаюсь синхронизировать повторяющуюся работу Hangfire с часами. По сути, я хочу, чтобы повторяющаяся работа начиналась со следующего часа, а затем каждый час.

Пример: если текущее время 21:04, повторяющееся задание должно быть следующим: 22:00 -> 11:00, 00:00, 01:00, 02:00 и т. Д.

Это похоже на мой предыдущий вопрос: Таймер C # тикает на каждый округленный час (буквально), но использует Hangfire.

В приведенном ниже коде я попытался сделать это сначала, запланировав BackgroundJob на минуты, оставшиеся до следующего часа, а затем RecurringJob на каждый час после выполнения BackgroundJob. Проблема в том, что он тикает в случайное время.

private DateTime RoundCurrentToNextOneHour()
{
    DateTime now = DateTime.Now, result = new DateTime(now.Year, now.Month, now.Day, now.Hour, 0, 0);
    return result.AddMinutes(((now.Minute / 60) + 1) * 60);
}

public Task StartAsync(CancellationToken cancellationToken)
{
    _logger.LogInformation("Timed Background Service is starting.");

    BackgroundJob.Schedule(() => StartRecurringJob(), RoundCurrentToNextOneHour());

    return Task.CompletedTask;
}

public void StartRecurringJob()
{
    RecurringJob.AddOrUpdate(() => DoWork(), Cron.Hourly, TimeZoneInfo.Local);
}
0
nop 15 Авг 2019 в 21:19

2 ответа

Лучший ответ

В этой строке кода вы всегда добавляете 60 минут.

result.AddMinutes(((now.Minute / 60) + 1) * 60)

Это связано с тем, что свойство Minute может быть только в значениях от 0 до 59 и, следовательно, уменьшается как:

result.AddMinutes((0 + 1) * 60)
result.AddMinutes(1 * 60)
result.AddMinutes(60)

Попробуйте это вместо этого:

result.AddMinutes((60 - (now.Minute % 60)) % 60)

Например, 09:00 будет выглядеть как 09:00, но с 09:01 через 09:59 будет округляться до 10:00. Похоже, это было поведение, которое вы просили.

Вы также можете прочитать в документах HangFire. о SchedulePollingInterval, которые могут повлиять на ваши результаты.

1
Matt Johnson-Pint 15 Авг 2019 в 19:17

Есть лучший способ сделать это, используя выражения cron. Если вы откроете https://crontab.guru и опробуете некоторые выражения, вы найдете объяснение для каждого из них.

Несколько примеров с выражениями cron:

  • каждые 5 минут: 0/5 * * * *.

Если текущее время было 23:12, он выполнял бы метод в 23:15, затем в 23:20 и так далее.

  • в каждый час будет 0 * * * *.

Если текущее время было 23:12, он выполнял бы метод в 00:00, 01:00, 02:00 и т. Д.

В дополнение к выражениям cron есть встроенные выражения cron. Их исходный код находится здесь: