dariogriffo dariogriffo - 3 months ago 70
C# Question

Hook to shutdown method in Quartz.net

I have a long running job that iterates over million of rows to do some tasks.
I want to be able to stop in the midle of this iteration if shutdown was requested for the job. Basically I have this

public class MyLongRunningJob : IJob
{
public void Execute(IJobExecutionContext context)
{
var rows = GetAllRows();
foreach(var row in rows)
{
DoSomething(row);
}
}
}


and I want something like this

public class MyLongRunningJob : IJob
{
bool _stop = false;
public void Execute(IJobExecutionContext context)
{
var rows = GetAllRows();
foreach(var row in rows)
{
if(_stop) break;
DoSomething(row);
}
}
}


Since the Execute method can take more than 1 hour I would like to set _stop to true at somepoint, I cannot find anything on the IJob or Scheduler to hookup when I call Shutdown of my scheduler.

This long running job is the only thing executed on my windows service and want to exit from the Execute method ASAP.

The windows service is a TopShelf service with Autofac and looks like

public class Service : IService
{
private readonly IScheduler _scheduler;

public Service(IScheduler scheduler)
{
_scheduler = scheduler;
}

public void Start()
{
_scheduler.Start();
}

public void Stop()
{
_scheduler.Shutdown();
}
}

Answer

So I was reading into Quartz. I've never used it before, but this thread was interesting Async/Await Support

After reading down, I noticed the current idea is to use IInterruptableJob which inherit IJob.

This allows the schedular to call the interrupt method to allow you stop your code "nicely". From the docs on that interface:

The means of actually interrupting the Job must be implemented within the itself (the method of this interface is simply a means for the scheduler to inform the that a request has been made for it to be interrupted). The mechanism that your jobs use to interrupt themselves might vary between implementations. However the principle idea in any implementation should be to have the body of the job's periodically check some flag to see if an interruption has been requested, and if the flag is set, somehow abort the performance of the rest of the job's work. An example of interrupting a job can be found in the source for the class Example7's DumbInterruptableJob It is legal to use some combination of and synchronization within and in order to have the method block until the signals that it has noticed the set flag.

I hope this helps.