58 lines
2.4 KiB
C#
58 lines
2.4 KiB
C#
using Microsoft.Extensions.Logging;
|
||
using PARR.Core.Common;
|
||
|
||
namespace PARR.Infrastructure.Interval
|
||
{
|
||
internal class IntervalService : IIntervalService
|
||
{
|
||
private readonly ILogger<IntervalService> logger;
|
||
|
||
public IntervalService(ILogger<IntervalService> logger)
|
||
{
|
||
this.logger = logger;
|
||
}
|
||
|
||
//public async Task IntervalInitAsync(IntervalHandlerDelegate intervalHandler, TimeSpan interval)
|
||
public async Task IntervalInitAsync(Func<Task> handler, TimeSpan interval)
|
||
{
|
||
logger.LogInformation("Инициализация интервального сервиса с интервалом: {Interval}", interval);
|
||
|
||
var nextStart = DateTimeOffset.UtcNow;
|
||
|
||
while (true)
|
||
{
|
||
nextStart = DateTimeOffset.UtcNow;
|
||
|
||
logger.LogInformation("Запуск по расписанию. Интервал: {interval}, дата: {nextStart}", interval, nextStart);
|
||
|
||
try
|
||
{
|
||
await handler.Invoke();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
logger.LogError(ex, "Ошибка при выполнении интервального обработчика");
|
||
}
|
||
|
||
nextStart = nextStart.Add(interval);
|
||
|
||
logger.LogInformation("Следующая дата запуска: {NextStart}. Интервал: {Interval}.", nextStart, interval);
|
||
|
||
var intervalOffset = nextStart - DateTimeOffset.UtcNow;
|
||
if (intervalOffset < TimeSpan.Zero)
|
||
{
|
||
intervalOffset = TimeSpan.Zero;
|
||
logger.LogWarning(
|
||
"Время следующего запуска изменено на текущее время. Рассчитанное время запуска ({NextStart}) меньше текущего времени ({Now}). " +
|
||
"Это произошло потому что время выполнения основного метода больше чем заданный интервал повторений.",
|
||
nextStart,
|
||
DateTimeOffset.UtcNow);
|
||
}
|
||
|
||
logger.LogDebug("Ожидание {Delay} перед следующим запуском", intervalOffset);
|
||
|
||
await Task.Delay(intervalOffset);
|
||
}
|
||
}
|
||
}
|
||
} |