Question

I've a job in Quartz.Net which triggers quite frequently, and sometimes runs for long, how do i cancel the trigger if the job is already running?

Was it helpful?

Solution

The more standard way is to use IInterruptableJob, see http://quartznet.sourceforge.net/faq.html#howtostopjob . Of course this is just another way to say if (!jobRunning)...

OTHER TIPS

Could you not just set some sort of global variable (jobRunning=true) when the job starts and revert it to false once it's finished?

Then when the trigger fires, just run your code if(jobRunning==false)

Your app could remove itself from the job list on startup and insert itself on shutdown.

Nowadays you could use "WithMisfireHandlingInstructionIgnoreMisfires" in your trigger and use [DisallowConcurrentExecution] attribute in your job.

This was my implementation (using the suggestions at the link that MarkoL gave earlier).

I'm just trying to save some typing.

I'm pretty new at Quartz.NET, so take the below with a train of salt.

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()));
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top