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

.NET 6控制台应用中Quartz.NET任务无法触发求助

.NET 6控制台Quartz.NET任务无法执行的问题排查与修复

核心问题1:调度器被立即终止

你的ScheduleQuartzNet方法中,刚完成任务调度就立刻调用await scheduler.Shutdown();,这会直接关掉Quartz调度器进程,任务根本没机会触发执行。

修复方式:
删掉await scheduler.Shutdown();,把调度器实例存为类成员,等应用退出时再关闭:

修改后的调度器代码:

private IScheduler _scheduler; // 保存调度器实例

public async Task ScheduleQuartzNet()
{
    _scheduler = await StdSchedulerFactory.GetDefaultScheduler();
    await _scheduler.Start();

    IJobDetail job = JobBuilder.Create<BackGroundJob>().Build();

    ITrigger trigger = TriggerBuilder.Create()
        .WithDailyTimeIntervalSchedule(schd => 
        {
            schd.WithIntervalInSeconds(20);
            schd.OnEveryDay();
            schd.StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(21,59));
        })
        .Build();

    try
    {
        await _scheduler.ScheduleJob(job, trigger);
        // 移除立即关闭调度器的代码
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

// 应用退出时调用此方法关闭调度器
public async Task ShutdownScheduler()
{
    if (_scheduler != null && !_scheduler.IsShutdown)
    {
        await _scheduler.Shutdown();
    }
}

核心问题2:Job的依赖注入未配置

BackGroundJob的构造函数依赖WorkerClass,但Quartz默认的SimpleJobFactory不支持构造函数注入,会导致创建Job实例时抛出异常——就算调度器正常运行,任务也执行不了。

修复方式:
推荐用Quartz官方的DI扩展包,步骤如下:

  1. 安装NuGet包:Quartz.Extensions.DependencyInjection
  2. 在Program.cs里配置Quartz服务:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = Host.CreateDefaultBuilder(args)
    .ConfigureServices(services =>
    {
        // 注册Quartz服务
        services.AddQuartz(q =>
        {
            q.AddJob<BackGroundJob>(j => j.WithIdentity("BackGroundJob"));
            q.AddTrigger(t => t
                .ForJob("BackGroundJob")
                .WithDailyTimeIntervalSchedule(s =>
                {
                    s.WithIntervalInSeconds(20);
                    s.OnEveryDay();
                    s.StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(21,59));
                })
                .WithIdentity("BackGroundJobTrigger"));
        });
        // 启动Quartz宿主服务,确保任务执行完成后再退出
        services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);

        // 把WorkerClass注册到DI容器
        services.AddScoped<WorkerClass>();
    })
    .Build();

await host.RunAsync();

额外问题:触发器配置可能不符合预期

你用WithDailyTimeIntervalSchedule并指定StartingDailyAt(21,59),意味着触发器只会在每天21:59之后才开始每隔20秒执行一次。如果当前时间早于21:59,任务要等到当天21:59才会首次触发。

如果需求是立即开始每隔20秒执行,换成SimpleTrigger:

ITrigger trigger = TriggerBuilder.Create()
    .WithSimpleSchedule(s => s
        .WithIntervalInSeconds(20)
        .RepeatForever())
    .Build();

调用代码调整

原调用代码里,await qs.ScheduleQuartzNet();后虽然有Console.ReadLine(),但之前调度器被提前关闭,根本没用。修改后要确保应用保持运行,等用户操作后再关闭调度器:

using BackgroundJob;

QuartzNetScheduler qs = new QuartzNetScheduler();
await qs.ScheduleQuartzNet();

Console.WriteLine("按任意键退出...");
Console.ReadKey();

// 退出前关闭调度器
await qs.ShutdownScheduler();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 22:14:58