如何安排后台服务来启动每个部署而无需控制器操作

问题描述 投票:0回答:1

我已经构建了一项服务来创建 erxcel 报告,该报告上传到云存储提供商。我正在创建一个计划任务,在每晚午夜运行该服务。我的问题是我经常重新部署我的应用程序以进行更新等,并且我试图弄清楚如何在每次重新部署时运行此后台任务。这可以自动完成还是我需要创建一个控制器操作并手动记住调用它以便任务开始?

我的代码如下:

public class ReviewSummaryBackgroundService : BackgroundService
{
    protected IReviewSummaryService _reviewSummaryService;
    
    public ReviewSummaryBackgroundService(IReviewSummaryService reviewSummaryService)
    {
        _reviewSummaryService = reviewSummaryService;
    }
    
    private static int SecondsUntilMidnight()
    {
        return (int)(DateTime.Today.AddDays(1.0) - DateTime.Now).TotalSeconds;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    var countdown = SecondsUntilMidnight();

    while (!stoppingToken.IsCancellationRequested)
    {
        if (countdown-- <= 0)
        {
            try
            {
                await OnTimerFiredAsync(stoppingToken);
            }
            catch(Exception ex)
            {
                // in future log exception
            }
            finally
            {
                countdown = SecondsUntilMidnight();
            }
        }
        await Task.Delay(1000, stoppingToken);
    }
}

    private async Task OnTimerFiredAsync(CancellationToken stoppingToken)
    {
        await _reviewSummaryService.ExportExcelReportAsync();
    }
}
asp.net-core background-service
1个回答
0
投票

假设您按如下方式注册后台服务,它将在您的应用程序启动时启动:

builder.Services.AddHostedService<ReviewSummaryBackgroundService>();

如果您想确保不会在每次本地调试尝试时创建报告,但在部署到产品环境时,您可以利用 ASPNETCORE_ENVIRONMENT

public ReviewSummaryBackgroundService(IWebHostEnvironment env, IReviewSummaryService reviewSummaryService) 
{
    _Env = env;
    //...
}

private static TimeSpan TimeUntilMidnight()
{
    return DateTime.Today.AddDays(1) - DateTime.Now;
}

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    var delay = _Env.IsProduction() ? TimeSpan.Zero : TimeUntilMidnight();
    
    while (!stoppingToken.IsCancellationRequested)
    {
        await Task.Delay(delay, stoppingToken);
        
        try
        {
            await OnTimerFiredAsync(stoppingToken);
        }
        catch (Exception ex)
        {
            // in future log exception
        }

        delay = TimeUntilMidnight();
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.