【问题标题】:Quartz.net multithreading and thread safetyQuartz.net 多线程和线程安全
【发布时间】:2019-11-05 07:42:38
【问题描述】:

我最近开始使用quartz.net,我有一个关于线程安全的问题。

public class QuartzService
    {
        public async Task Start()
        {
            // construct a scheduler factory
            NameValueCollection props = new NameValueCollection
            {
                { "quartz.serializer.type", "binary" }
            };
            StdSchedulerFactory factory = new StdSchedulerFactory(props);

            // get a scheduler
            IScheduler sched = await factory.GetScheduler();

            // define the job and tie it to our HelloJob class
            IJobDetail job = JobBuilder.Create<TestJob>().StoreDurably()
                .WithIdentity("myJob", "jobGroup1")
                .Build();

            await sched.AddJob(job, true);

            // Trigger the job to run now, and then every 40 seconds
            ITrigger trigger1 = TriggerBuilder.Create()
                .WithIdentity("myTrigger1", "group1")
                .StartNow()
                .WithSimpleSchedule(x => x
                    .WithIntervalInSeconds(5)
                    .RepeatForever())
                .ForJob(job)
                .Build();

            // Trigger the job to run now, and then every 40 seconds
            ITrigger trigger2 = TriggerBuilder.Create()
                .WithIdentity("myTrigger2", "group1")
                .StartNow()
                .WithSimpleSchedule(x => x
                    .WithIntervalInSeconds(5)
                    .RepeatForever())
                .ForJob(job)
                .Build();

            await sched.ScheduleJob(trigger1);
            await sched.ScheduleJob(trigger2);

            await sched.Start();
        }
    }



 public class TestJob : IJob
    {
        public async Task Execute(IJobExecutionContext context)
        {
            await Console.Out.WriteLineAsync($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
        }
    }

在上面的例子中,我有一个有两个触发器的工作。我的问题是这两个触发器在运行时是否共享同一个作业实例?或者每次触发器运行时都会创建一个新的 IJobDetail 实例。我曾尝试阅读quartz.net 的文档,但它非常混乱,因为它将 JobDetail 实例与作业实例混合在一起,而且我不太清楚这里的情况。

【问题讨论】:

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


    【解决方案1】:

    使用默认作业工厂SimpleJobFactory,为每个作业调用创建一个给定作业类型(CLR 类型)的新对象实例。默认情况下,CLR 意义上的作业对象实例永远不会被触发器共享。

    但是,可以创建一个自定义作业工厂,该工厂可以从控制容器的反转中返回单例。

    还要区分工作类型。 JobDetails 描述了一种作业类型,多个触发器可以指向相同的细节(因此是相同的类型)。这导致如果作业没有应用PreventConcurrentExecutionAttribute,则可能有多个相同CLR 类型的作业同时运行。为了让事情变得有趣,PreventConcurrentExecutionAttribute 应用于作业详细信息,因此两个不同的作业详细信息(不同的作业密钥)但相同的类型可以再次同时运行。

    【讨论】:

    • 感谢您的回复。您是什么意思“可以同时运行两个作业实例”?
    • 如果您有两个或多个触发器触发相同的作业详细信息(即相同的身份,通过作业密钥)并且它们同时触发或者由于作业运行而执行重叠长。此外,如果单个触发器触发作业,例如每 10 秒触发一次,并且作业执行需要 30 秒,那么您可以同时运行三个作业,即使它们可能会竞争相同的资源。
    • 谢谢。问题没有回答。对最初问题的简单回答。 “我的问题是这两个触发器在运行时是否共享同一个作业实例”?
    • 我试图澄清我的答案,简短的回答:触发器不共享相同的作业对象实例
    猜你喜欢
    • 2022-11-21
    • 2012-11-24
    • 1970-01-01
    • 2012-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多