【问题标题】:Quartz.net 3 trigger fires another jobQuartz.net 3 触发器触发另一个工作
【发布时间】:2019-05-16 01:55:21
【问题描述】:

我正在为我的 .net core 2.2 应用程序设置quartz.net 3.0.7。如果我在“服务”中添加了一项工作,那么一切都会完美无缺。但是,当我添加第二份工作时。第一份工作的触发以某种方式触发了第二份工作。

我的石英扩展方法:

public static void AddQuartz(this IServiceCollection services, string configuration)
{
    services.AddSingleton<IJobFactory, ScheduledJobFactory>();

    var properties = new NameValueCollection
    {
        ["quartz.serializer.type"] = "json",
        ["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz",
        ["quartz.jobStore.useProperties"] = "false",
        ["quartz.jobStore.dataSource"] = "sqlserver",
        ["quartz.jobStore.tablePrefix"] = "QRTZ_",
        ["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz",
        //["quartz.dataSource.sqlserver.provider"] = "SqlServer-41", // SqlServer-41 is the new provider for .NET Core
        ["quartz.dataSource.sqlserver.provider"] = "SqlServer",
        ["quartz.dataSource.sqlserver.connectionString"] = configuration
    };
    services.AddSingleton<IScheduler>(provider =>
    {
        var schedulerFactory = new StdSchedulerFactory(properties);
        var scheduler = schedulerFactory.GetScheduler().Result;
        scheduler.JobFactory = provider.GetService<IJobFactory>();
        //scheduler.ScheduleJob(JobTrigger);
        return scheduler;
    });

}

public static void AddJob(this IServiceCollection services, Type job)
{
    services.Add(new ServiceDescriptor(typeof(IJob), job, ServiceLifetime.Singleton));
}

public static void StartRepetitiveJob<TJob>(this IScheduler scheduler, TimeSpan runInterval, DateTimeOffset startWhen) where TJob : IJob
{
    var jobName = typeof(TJob).FullName;

    var job = JobBuilder.Create<TJob>()
        .WithIdentity(jobName,jobName)
        .StoreDurably()
        .Build();

    var trigger = TriggerBuilder.Create()
        .WithIdentity($"{jobName}.trigger", $"{jobName}.trigger")
        .StartAt(startWhen)
        .WithSimpleSchedule(scheduleBuilder =>
            scheduleBuilder
                .WithInterval(runInterval)
                .RepeatForever())
                .ForJob(job)
        .Build();

    scheduler.ScheduleJob(job, trigger);
}

public static void FireJobOnlyOnce<TJob>(this IScheduler scheduler, DateTime fireat, IDictionary<string, object> dictionary) where TJob : IJob
{
    var jobName = typeof(TJob).FullName;
    var jobDataMap = new JobDataMap(dictionary);
    var job = JobBuilder.Create<TJob>()
        .WithIdentity(jobName,jobName)
        //.WithIdentity(jobName, Guid.NewGuid().ToString())
        .SetJobData(jobDataMap)
        .StoreDurably()
        .Build();

    var trigger = (ISimpleTrigger) TriggerBuilder.Create()
        .WithIdentity($"{jobName}.trigger", $"{jobName}.trigger")
        .StartAt(fireat.ToUniversalTime()) 
        .UsingJobData(jobDataMap)
        .ForJob(job)
        .Build();
    scheduler.ScheduleJob(job, trigger);
}

startup.cs 中:

services.AddQuartz(Configuration.GetConnectionString("DefaultConnection"));
        services.AddJob(typeof(CheckPropertyListingJob));
        services.AddJob(typeof(ScheduledGetPropertyDataJob));

program.cs 中:

            DateTime dt = DateTime.UtcNow;
        TimeSpan interval = TimeSpan.FromHours(6);
        scheduler.StartRepetitiveJob<CheckPropertyListingJob>(interval, new DateTimeOffset(dt.Add(TimeSpan.FromMinutes(2)), TimeSpan.Zero));

所以,当我只添加CheckPropertyListingJob 时,一切都很好。但是当我添加ScheduledGetPropertyDataJob 时,为CheckPropertyListingJob 创建的触发器会触发另一个工作。

【问题讨论】:

    标签: c# .net-core quartz.net


    【解决方案1】:

    好吧,我终于解决了这个问题。我在一个只有一份工作的教程之后开始实施石英。所以我的 ScheduledJobFactory 看起来像这样:

        public class ScheduledJobFactory: IJobFactory
    {
        private readonly IServiceProvider serviceProvider;
    
        public ScheduledJobFactory(IServiceProvider serviceProvider)
        {
            this.serviceProvider = serviceProvider;
        }
    
        public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
        {
            return serviceProvider.GetService(typeof(IJob)) as IJob;
        }
    
        public void ReturnJob(IJob job)
        {
            var disposable = job as IDisposable;
            disposable?.Dispose();
        }
    }
    

    我根据answer 编辑了 NewJob 方法,一切都很好。我不敢相信我会如此不注意。

                return (IJob)serviceProvider.GetService(bundle.JobDetail.JobType);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多