You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ASP.NET Core中借助Hangfire触发每日汇总邮件发送任务

嘿,我来帮你梳理几种在ASP.NET Core里触发每日汇总邮件任务的可行方案,都是实际项目里常用的:

方案一:用ASP.NET Core原生Hosted Service(后台定时任务)

这是最轻量化的方案,不需要额外依赖,适合简单的每日定时场景。核心思路是创建一个后台服务,让它定期调用你的SendAllSummaries方法。

首先创建一个继承自BackgroundService的类:

public class DailySummaryHostedService : BackgroundService
{
    private readonly IServiceProvider _serviceProvider;
    private readonly ILogger<DailySummaryHostedService> _logger;

    public DailySummaryHostedService(IServiceProvider serviceProvider, ILogger<DailySummaryHostedService> logger)
    {
        _serviceProvider = serviceProvider;
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("每日汇总邮件后台服务已启动");

        while (!stoppingToken.IsCancellationRequested)
        {
            try
            {
                // 因为你的SummaryEmailBusiness依赖Scoped服务(比如DbContext),所以要创建服务范围
                using (var scope = _serviceProvider.CreateScope())
                {
                    var summaryBiz = scope.ServiceProvider.GetRequiredService<SummaryEmailBusiness>();
                    summaryBiz.SendAllSummaries();
                    _logger.LogInformation("今日汇总邮件已全部发送");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "发送汇总邮件时出现错误");
            }

            // 计算到下一次执行的延迟(比如每天凌晨2点执行,避免时间漂移)
            var nextRunTime = GetNextScheduledTime();
            var delay = nextRunTime - DateTime.Now;
            await Task.Delay(delay, stoppingToken);
        }

        _logger.LogInformation("每日汇总邮件后台服务已停止");
    }

    // 自定义方法:获取下一次执行的时间(比如每天凌晨2点)
    private DateTime GetNextScheduledTime()
    {
        var now = DateTime.Now;
        var nextRun = new DateTime(now.Year, now.Month, now.Day, 2, 0, 0);
        
        // 如果当前时间已经过了2点,就推迟到第二天的2点
        if (nextRun <= now)
        {
            nextRun = nextRun.AddDays(1);
        }
        return nextRun;
    }
}

然后在ConfigureServices里注册这个后台服务:

services.AddHostedService<DailySummaryHostedService>();
方案二:用Hangfire(强大的任务调度框架)

如果你的需求更复杂——比如需要任务重试、可视化管理、支持Cron表达式的灵活调度,那Hangfire是个很棒的选择。

步骤如下:

  1. 先安装必要的NuGet包:

    Install-Package Hangfire.AspNetCore
    Install-Package Hangfire.SqlServer // 如果你用SQL Server存储任务数据
    
  2. 在ConfigureServices里配置Hangfire:

    services.AddHangfire(config => 
        config.UseSqlServerStorage(Configuration.GetConnectionString("DefaultConnection")));
    services.AddHangfireServer();
    
  3. (可选)在Configure里启用Hangfire仪表盘,方便你查看和管理任务:

    app.UseHangfireDashboard("/hangfire"); // 访问路径可以自定义
    
  4. 注册每日定时任务,比如在Program.cs的应用启动后添加:

    // 每天凌晨2点执行,Cron表达式"0 0 2 * * ?"表示每天2点0分0秒触发
    RecurringJob.AddOrUpdate<SummaryEmailBusiness>(
        biz => biz.SendAllSummaries(),
        "0 0 2 * * ?",
        TimeZoneInfo.Local);
    

Hangfire会自动处理依赖注入,还自带失败重试、任务日志等功能,非常省心。

方案三:用外部调度工具触发(Cron/Windows任务计划)

如果不想把调度逻辑放在应用内部,或者你的应用不是长期运行的(比如服务器会定期重启),可以写一个API接口,然后用外部工具定时调用它。

首先创建一个API控制器:

[ApiController]
[Route("api/summary")]
public class SummaryController : ControllerBase
{
    private readonly SummaryEmailBusiness _summaryBiz;

    public SummaryController(SummaryEmailBusiness summaryBiz)
    {
        _summaryBiz = summaryBiz;
    }

    [HttpPost("send-all")]
    public IActionResult TriggerSendAll()
    {
        _summaryBiz.SendAllSummaries();
        return Ok("汇总邮件发送任务已启动");
    }
}

然后用外部工具定时调用这个接口:

  • Linux系统:编辑Cron任务,添加一行(每天凌晨2点调用):
    0 2 * * * curl -X POST https://your-app-domain/api/summary/send-all
    
  • Windows系统:打开「任务计划程序」,创建一个定时任务,每天凌晨2点执行PowerShell命令:
    Invoke-RestMethod -Uri "https://your-app-domain/api/summary/send-all" -Method Post
    

最后给你个选型参考:

  • 只是简单的每日定时,选Hosted Service就行,原生无依赖;
  • 需要复杂调度、任务管理,选Hangfire;
  • 想把调度和应用彻底分离,或者应用不长期运行,选外部调度工具。

内容的提问来源于stack exchange,提问作者Guerrilla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:37:51