You need to enable JavaScript to run this app. Quartz.NET 5自定义JobFactory注册后无法触发问题求助
优惠活动
大模型
产品
解决方案
定价
更多

Quartz.NET 5自定义JobFactory注册后无法触发问题求助

问题原因

你在配置Quartz时同时调用了UseJobFactory<JobFactory>()和UseMicrosoftDependencyInjectionJobFactory(),后者是Quartz官方提供的适配.NET依赖注入的默认JobFactory实现,执行顺序靠后的它会覆盖你前面自定义的JobFactory配置,导致自定义逻辑不生效。同时你仅注册了JobFactory本身的实例,Quartz默认会按IJobFactory接口类型从容器中拉取实例,也会导致自定义工厂无法被正确加载。

正确配置步骤

  1. 移除Quartz配置中的UseMicrosoftDependencyInjectionJobFactory()调用,避免覆盖自定义JobFactory配置
  2. 将自定义JobFactory注册为IJobFactory接口的实现,而不是仅注册自身类型
  3. 确保你自己实现的所有业务Job类,以及ILogTime等依赖都已注册到DI容器中

完整注册示例

// 1. 注册业务依赖
services.AddSingleton<ILogTime, 你的LogTime实现类>();
// 注册所有自定义业务Job,按你的需求选Transient/Scoped生命周期
services.AddTransient<你的业务Job类>();

// 2. 注册自定义JobFactory为IJobFactory的实现
services.AddSingleton<IJobFactory, JobFactory>();

// 3. 配置Quartz
services.AddQuartz(q =>
{
    q.SchedulerId = "MyJob";
    q.SchedulerName = "MyJob";
    
    // 仅保留自定义JobFactory的注册
    q.UseJobFactory<JobFactory>();

    // 这里正常注册你的Job和Trigger即可,示例:
    q.AddJob<你的业务Job类>(opts => opts.WithIdentity("TestJob"));
    q.AddTrigger(opts => opts
        .ForJob("TestJob")
        .WithIdentity("TestJobTrigger")
        .WithSimpleSchedule(x => x.WithIntervalInSeconds(10).RepeatForever()));
});

services.AddQuartzHostedService(options =>
{
    options.WaitForJobsToComplete = true;
});

可选优化:适配Scoped生命周期服务

如果你有注册为Scoped生命周期的依赖,直接用根容器解析会出现生命周期不匹配的问题,建议对JobFactory和装饰器做如下修改:

// 修改JobFactory的NewJob方法,创建Scope解析服务
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
    var scope = _container.CreateScope();
    var job = (IJob)scope.ServiceProvider.GetRequiredService(bundle.JobDetail.JobType);
    var logTime = scope.ServiceProvider.GetRequiredService<ILogTime>();
    return new JobLogDecorator(job, logTime, scope);
}

// 给JobLogDecorator增加Scope持有和释放逻辑
public class JobLogDecorator : IJob, IDisposable
{
    private readonly IJob _decorated;
    private readonly ILogTime _log;
    private readonly IServiceScope _scope;

    public JobLogDecorator (IJob decorated, ILogTime log, IServiceScope scope)
    {
        _decorated = decorated;
        _log = log;
        _scope = scope;
    }

    public async Task Execute(IJobExecutionContext context)
    {
        var jobName = context.JobDetail.Key.Name;
        var sw = Stopwatch.StartNew();
        await _decorated.Execute(context);
        _log.Log(sw.ElapsedMilliseconds, jobName);
    }

    public void Dispose()
    {
        (_decorated as IDisposable)?.Dispose();
        _scope.Dispose();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 21:30:02