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

如何通过API和端点动态创建Quartz.Net任务调度器

Quartz.Net 动态任务管理实现方案

核心结论

Quartz.Net 完全支持运行时动态创建、管理任务,绝对不局限于在Program.cs中初始化配置,完全适配你描述的从数据库加载初始任务、API动态新增任务的场景。

实现步骤与关键代码

1. 应用启动时加载数据库初始任务

在应用启动完成后,读取ScheduledTasks表数据,逐个创建Job和Trigger并加入调度器,推荐用IHostedService来实现启动加载逻辑:

public class TaskLoaderHostedService : IHostedService
{
    private readonly IScheduler _scheduler;
    private readonly YourDbContext _dbContext;

    public TaskLoaderHostedService(IScheduler scheduler, YourDbContext dbContext)
    {
        _scheduler = scheduler;
        _dbContext = dbContext;
    }

    public async Task StartAsync(CancellationToken cancellationToken)
    {
        await _scheduler.Start(cancellationToken);
        
        // 读取数据库中所有待调度任务
        var tasks = await _dbContext.ScheduledTasks.ToListAsync(cancellationToken);
        foreach (var task in tasks)
        {
            // 构建Job详情,绑定自定义Job类型
            var jobDetail = JobBuilder.Create<YourCustomJob>()
                .WithIdentity(task.TaskId.ToString(), task.TaskGroup)
                .UsingJobData("TaskParam", task.TaskParam) // 传递任务参数
                .Build();

            // 构建Trigger,使用数据库存储的Cron表达式
            var trigger = TriggerBuilder.Create()
                .WithIdentity($"trigger_{task.TaskId}", task.TaskGroup)
                .WithCronSchedule(task.CronExpression)
                .Build();

            // 将任务加入调度器
            await _scheduler.ScheduleJob(jobDetail, trigger, cancellationToken);
        }
    }

    public async Task StopAsync(CancellationToken cancellationToken)
    {
        await _scheduler.Shutdown(cancellationToken);
    }
}

然后在Program.cs中注册这个HostedService:

builder.Services.AddHostedService<TaskLoaderHostedService>();

2. API调用时动态新增任务

创建API接口,先将用户提交的任务信息写入数据库,再创建对应的Job和Trigger加入调度器:

[ApiController]
[Route("api/scheduled-tasks")]
public class ScheduledTasksController : ControllerBase
{
    private readonly IScheduler _scheduler;
    private readonly YourDbContext _dbContext;

    public ScheduledTasksController(IScheduler scheduler, YourDbContext dbContext)
    {
        _scheduler = scheduler;
        _dbContext = dbContext;
    }

    [HttpPost]
    public async Task<IActionResult> AddNewTask([FromBody] NewTaskRequest request)
    {
        // 1. 写入数据库
        var dbTask = new ScheduledTask
        {
            TaskGroup = request.TaskGroup,
            CronExpression = request.CronExpression,
            TaskParam = request.TaskParam,
            // 填充其他必要字段
        };
        _dbContext.ScheduledTasks.Add(dbTask);
        await _dbContext.SaveChangesAsync();

        // 2. 创建并调度任务
        var jobDetail = JobBuilder.Create<YourCustomJob>()
            .WithIdentity(dbTask.TaskId.ToString(), dbTask.TaskGroup)
            .UsingJobData("TaskParam", dbTask.TaskParam)
            .Build();

        var trigger = TriggerBuilder.Create()
            .WithIdentity($"trigger_{dbTask.TaskId}", dbTask.TaskGroup)
            .WithCronSchedule(dbTask.CronExpression)
            .Build();

        await _scheduler.ScheduleJob(jobDetail, trigger);

        return Ok(new { TaskId = dbTask.TaskId });
    }
}

3. 关键注意事项

  • 自定义Job类型:必须实现IJob接口,在Execute方法中编写具体的任务逻辑,比如:
    public class YourCustomJob : IJob
    {
        public async Task Execute(IJobExecutionContext context)
        {
            var taskParam = context.JobDetail.JobDataMap.GetString("TaskParam");
            // 执行任务逻辑
            await Task.CompletedTask;
        }
    }
    
  • 唯一性保障:用数据库的TaskId作为Job和Trigger的标识,避免重复调度。
  • 异常处理:在加载和创建任务时添加异常捕获,防止单个任务失败影响整体流程。
  • 状态持久化:如果需要Quartz自身维护任务运行状态,可以配置ADO.NET JobStore;如果依赖自己的数据库,只需在应用重启时重新加载即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 12:27:26