【问题标题】:Unable to create job with trigger with Quartz.NET无法使用 Quartz.NET 触发器创建作业
【发布时间】:2019-11-23 11:20:45
【问题描述】:

我有一个 .NET Core 3 辅助服务,它使用 Quartz.NET 来安排作业。在这个精简的示例中,我有一个带有单个触发器的工作。它似乎没有运行,我也没有遇到任何异常。

  • 如何调试 Quartz.NET 并获取作业和触发器列表?
  • 为什么下面示例中的作业没有运行?

我已尝试在组内创建作业和触发器,而没有组则无效。

public class Worker : BackgroundService
{
    private readonly ILogger<Worker> _logger;
    private readonly ISchedulerFactory _schedulerFactory;

    public Worker(ILogger<Worker> logger, ISchedulerFactory schedulerFactory)
    {
        _logger = logger;
        _schedulerFactory = schedulerFactory;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        NameValueCollection props = new NameValueCollection
        {
            { "quartz.serializer.type", "binary" }
        };

        StdSchedulerFactory factory = new StdSchedulerFactory(props);

        IScheduler schedulder = await factory.GetScheduler().ConfigureAwait(false);
        await schedulder.Start().ConfigureAwait(false);

        var pingJob = JobBuilder.Create<PingJob>()
            .WithIdentity("ping-job")
            .Build();

        ITrigger pingJob1Trigger = TriggerBuilder.Create()
            .WithIdentity("ping-job")
            .WithSimpleSchedule(x => x
                .WithInterval(TimeSpan.FromSeconds(1))
                .RepeatForever())
            .StartNow()
            .Build();

        await schedulder.ScheduleJob(pingJob, pingJob1Trigger, stoppingToken).ConfigureAwait(false);
    }
}

工作:

public class PingJob : IJob
{
    private readonly ILogger<PingJob> _logger;

    public PingJob(ILogger<PingJob> logger)
    {
        _logger = logger;
    }

    public async Task Execute(IJobExecutionContext context)
    {
        _logger.LogInformation("Ping");


        await Task.CompletedTask;
    }
}

【问题讨论】:

    标签: c# quartz.net


    【解决方案1】:

    Quartz 将使用默认的无参数构造函数创建作业。在您当前的PingJob 构造函数中设置断点,启动调试器并观察断点不会被命中。

    这是描述此行为的文档的相关部分:

    当触发器触发时,它所关联的 Job 将通过以下方式实例化 在 Scheduler 上配置的 JobFactory。默认的 JobFactory 只需激活作业类的新实例。你可能想要 创建自己的 JobFactory 实现来完成诸如此类的事情 就像让你的应用程序的 IoC 或 DI 容器产生/初始化 作业实例。

    查看 IJobFactory 接口,以及相关的 Scheduler.SetJobFactory(fact) 方法。

    现在添加一个无参数构造函数

    public PingJob() 
    { 
    }
    

    在其中设置断点,启动调试器,它将被命中。您还可以在Execute 方法中设置断点,它现在也会被命中。

    您现在可以如下替换Execute 方法,它将在控制台上打印Ping

    public async Task Execute(IJobExecutionContext context)
    {
        await Console.Out.WriteLineAsync("Ping");
    }
    

    我们如何才能让您的原始代码正常工作?正如文档所说,我们需要使用JobFactory。参见例如stackoverflow问题.net Core Quartz Dependency Injection

    【讨论】:

    • 我已经在使用库来设置 Quartz.NET 以使用 DI。
    • 您使用哪个库?您可以在配置 DI 容器和设置 Quartz.NET 的位置发布代码吗?
    • @user9993 Marius 是对的,您需要自己实现IJobFactory,Quartz 在发生异常时会吞下异常,并且在您使用的标准配置中,您看不到有什么问题。我给一个类似的问题写了answer,也许它会帮助你解决你的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多