【问题标题】:Long running jobs in Quartz.NetQuartz.Net 中长时间运行的作业
【发布时间】:2009-09-10 13:32:23
【问题描述】:

我在 Quartz.Net 中有一个工作触发频率很高,有时会运行很长时间,如果工作已经在运行,我该如何取消触发?

【问题讨论】:

    标签: .net quartz-scheduler


    【解决方案1】:

    更标准的方法是使用 IInterruptableJob,参见http://quartznet.sourceforge.net/faq.html#howtostopjob。当然,这只是另一种说法 if (!jobRunning)...

    【讨论】:

    • 只是该类的一个实例,它实现了一次允许的 IInterruptableJob,还是一个使用该类的 Job?
    • 如果您想一次只允许一个实例,那么 IStatefulJob 是您的理想选择,quartznet.sourceforge.net/faq.html#howtopreventconcurrentfire。 IInterruptableJob 只是为您提供了一种发出中断信号的标准方式,您需要在工作方面进行繁重的工作(检查是否已引发中断标志)。
    【解决方案2】:

    您能否在作业开始时设置某种全局变量 (jobRunning=true),并在作业完成后将其恢复为 false?

    然后当触发器触发时,只需运行您的代码 if(jobRunning==false)

    【讨论】:

    • 是的,通常最简单的解决方案是最好的。我已经实现了这个,我虽然有一个实现的解决方案,它暂停了工作,直到第一个完成,但无论如何,这工作得很好!
    【解决方案3】:

    您的应用可以在启动时将自己从作业列表中删除,并在关闭时将自己插入。

    【讨论】:

      【解决方案4】:

      现在,您可以在触发器中使用“WithMisfireHandlingInstructionIgnoreMisfires”,并在工作中使用 [DisallowConcurrentExecution] 属性。

      【讨论】:

        【解决方案5】:

        这是我的实现(使用 MarkoL 之前提供的链接中的建议)。

        我只是想节省一些输入。

        我是 Quartz.NET 的新手,所以请用下面的方法来补充一下。

        public class AnInterruptableJob : IJob, IInterruptableJob
        {
        
            private bool _isInterrupted = false;
        
            private int MAXIMUM_JOB_RUN_SECONDS = 10;
        
            /// <summary> 
            /// Called by the <see cref="IScheduler" /> when a
            /// <see cref="ITrigger" /> fires that is associated with
            /// the <see cref="IJob" />.
            /// </summary>
            public virtual void Execute(IJobExecutionContext context)
            {
        
        
                /* See http://aziegler71.wordpress.com/2012/04/25/quartz-net-example/ */
        
                JobKey key = context.JobDetail.Key;
        
                JobDataMap dataMap = context.JobDetail.JobDataMap;
        
                int timeOutSeconds = dataMap.GetInt("TimeOutSeconds");
                if (timeOutSeconds <= 0)
                {
                    timeOutSeconds = MAXIMUM_JOB_RUN_SECONDS;
                }
        
                Timer t = new Timer(TimerCallback, context, timeOutSeconds * 1000, 0);
        
        
                Console.WriteLine(string.Format("AnInterruptableJob Start : JobKey='{0}', timeOutSeconds='{1}' at '{2}'", key, timeOutSeconds, DateTime.Now.ToLongTimeString()));
        
        
                try
                {
                    Thread.Sleep(TimeSpan.FromSeconds(7));
                }
                catch (ThreadInterruptedException)
                {
                }
        
        
                if (_isInterrupted)
                {
                    Console.WriteLine("Interrupted.  Leaving Excecute Method.");
                    return;
                }
        
                Console.WriteLine(string.Format("End AnInterruptableJob (should not see this) : JobKey='{0}', timeOutSeconds='{1}' at '{2}'", key, timeOutSeconds, DateTime.Now.ToLongTimeString()));
        
            }
        
        
            private void TimerCallback(Object o)
            {
                IJobExecutionContext context = o as IJobExecutionContext;
        
                if (null != context)
                {
                    context.Scheduler.Interrupt(context.FireInstanceId);
                }
            }
        
            public void Interrupt()
            {
                _isInterrupted = true;
                Console.WriteLine(string.Format("AnInterruptableJob.Interrupt called at '{0}'", DateTime.Now.ToLongTimeString()));
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-09-28
          • 1970-01-01
          • 2020-04-26
          • 1970-01-01
          • 1970-01-01
          • 2023-03-27
          相关资源
          最近更新 更多