在.Net Core 3.0中每天午夜运行BackgroundService

lg40wkob  于 2023-02-01  发布在  .NET
关注(0)|答案(4)|浏览(324)

我希望每天午夜运行后台服务。.NET核心默认BackgroundService运行在task.delay上,我希望每天午夜运行此服务(24小时间隔)。
我遇到的问题是BackgroundService每隔task.Delay间隔运行一次,而不是指定特定时间。

public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;
        private readonly IServiceScopeFactory _serviceScopeFactory;

        public Worker(ILogger<Worker> logger, IServiceScopeFactory serviceScopeFactory)
        {
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
            _serviceScopeFactory = serviceScopeFactory ?? throw new ArgumentNullException(nameof(serviceScopeFactory));
        }
        protected override async Task ExecuteAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                // We ultimately resolve the actual services we use from the scope we create below.
                // This ensures that all services that were registered with services.AddScoped<T>()
                // will be disposed at the end of the service scope (the current iteration).
                using var scope = _serviceScopeFactory.CreateScope();

                var configuration = scope.ServiceProvider.GetRequiredService<IWorkFlowScheduleService>();
                configuration.DailySchedule(dateTime: DateTime.Now);

                _logger.LogInformation($"Sending message to ");

                await Task.Delay(TimeSpan.FromSeconds(10), cancellationToken);
            }
        }
    }
dojqjjoe

dojqjjoe1#

这是我的解决方案。

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
 {
     do
     {
         int hourSpan = 24 - DateTime.Now.Hour;
         int numberOfHours = hourSpan;

         if (hourSpan == 24)
         {
             //do something
             numberOfHours = 24;
         }

         await Task.Delay(TimeSpan.FromHours(numberOfHours), stoppingToken);
     }
     while (!stoppingToken.IsCancellationRequested);
 }
jyztefdp

jyztefdp2#

放入一个初始的Task.Delay,等待到午夜,做任何你需要做的事情,然后Task.Delay 24小时,怎么样?

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    // calculate seconds till midnight
    var now = DateTime.Now;
    var hours = 23 - now.Hour;
    var minutes = 59 - now.Minute;
    var seconds = 59 - now.Second;
    var secondsTillMidnight = hours * 3600 + minutes * 60 + seconds;

    // wait till midnight
    await Task.Delay(TimeSpan.FromSeconds(secondsTillMidnight), stoppingToken);

    while (!stoppingToken.IsCancellationRequested)
    {
        // do stuff
        _logger.LogInformation($"Sending message to ");

        // wait 24 hours
        await Task.Delay(TimeSpan.FromHours(24), stoppingToken);
    }
}
mcdcgff0

mcdcgff03#

我使用NCrontab 3.3.1
https://www.nuget.org/packages/ncrontab/
这样,您就可以使用cron;否则,我会同意前面的一个评论,即创建一个控制台应用程序,并将其作为cron或服务直接在服务器上运行。
下面是我如何实现NCrontab的一个示例。

public class YourServiceName : BackgroundService
{
    private CrontabSchedule _schedule;
    private DateTime _nextRun;
    // My CrontabHelper class simply returns a string representing a cron schedule. You can just use 0 0 0 * * * to run every day at midnight instead
    private string Schedule => CrontabHelper.Schedule(CrontabHelper.CronType.Day); 

    public YourServiceName()
    {
        _schedule = CrontabSchedule.Parse(Schedule, new CrontabSchedule.ParseOptions { IncludingSeconds = true });
        _nextRun = _schedule.GetNextOccurrence(DateTime.Now);
    }

    protected async override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        do
        {
            var now = DateTime.Now;
            if (now > _nextRun)
            {
                // DO WORK HERE
            }

            await Task.Delay(5000, stoppingToken);
        }
        while (!stoppingToken.IsCancellationRequested);
    }
}

那么在你的程序里. cs包括这个

builder.Services.AddHostedService<YourServiceName>();

希望这有帮助!

piztneat

piztneat4#

您可以使用Quartz.NET库提供后台服务。

相关问题