Use the DisallowConcurrentExecution attribute.
Declare your class as follows:
[DisallowConcurrentExecution]
public class SomeTask : IJob
{
}
Misfires
"Misfire Instructions Another important property of a Trigger is its
"misfire instruction". A misfire occurs if a persistent trigger
"misses" its firing time because of the scheduler being shutdown, or
because there are no available threads in Quartz.NET's thread pool for
executing the job. The different trigger types have different misfire
instructions available to them. By default they use a 'smart policy'
instruction - which has dynamic behavior based on trigger type and
configuration. When the scheduler starts, it searches for any
persistent triggers that have misfired, and it then updates each of
them based on their individually configured misfire instructions. When
you start using Quartz.NET in your own projects, you should make
yourself familiar with the misfire instructions that are defined on
the given trigger types, and explained in their API documentation.
More specific information about misfire instructions will be given
within the tutorial lessons specific to each trigger type."
Check out the "trigger misfire instructions" information at the bottom of these pages:
Lesson 5: SimpleTrigger
Lesson 6: CronTrigger
Old Quartz.NET API answer:
http://quartznet.sourceforge.net/apidoc/topic142.html:
IStatefulJob instances follow slightly different rules from regular
IJob instances. The key difference is
that their associated JobDataMap is
re-persisted after every execution of
the job, thus preserving state for the
next execution. The other difference
is that stateful jobs are not allowed
to Execute concurrently, which means
new triggers that occur before the
completion of the IJob.Execute method
will be delayed.
So, declare your 'Job' class as follows:
class DocumentImportJob : IStatefulJob
{
......
}
To avoid delayed tasks re-firing immediately after job completes (when the job takes more than 1 minute and causes a trigger 'misfire'), do the following when creating your trigger(s) (adjust depending on the trigger type used):
myJobTrigger.MisfireInstruction = MisfireInstruction.CronTrigger.DoNothing;
https://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/more-about-triggers.html
you can use AdoJobStore.
Quartz.net will use a set of tables with prefix QRTZ_
(you can change it if you want) in your database to stored jobs, triggers and status of these objects.
I guess you want to have a table in your DB where you're going to keep extended information about your schedules, right?
You won't access Quartz.net table directly cause you will use the APIs provided by Quartz.net.
The process to create a job detail and trigger is straightforward and described very well in the tutorials.
To configure your app to use the AdoJobStore you have to specify few informations in your app.config file.
Here is an example:
<quartz>
<add key="quartz.scheduler.instanceName" value="myApp" />
<add key="quartz.scheduler.instanceId" value="MyApp" />
<!-- Configure Thread Pool -->
<add key="quartz.threadPool.type"
value="Quartz.Simpl.SimpleThreadPool, Quartz" />
<add key="quartz.threadPool.threadCount" value="10" />
<add key="quartz.threadPool.threadPriority" value="Normal" />
<!-- Configure Job Store -->
<add key="quartz.jobStore.misfireThreshold" value="60000" />
<add key="quartz.jobStore.type"
value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz" />
<add key="quartz.jobStore.useProperties" value="true" />
<add key="quartz.jobStore.dataSource" value="default" />
<add key="quartz.jobStore.tablePrefix" value="QRTZ_" />
<add key="quartz.jobStore.lockHandler.type"
value="Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz" />
<add key="quartz.dataSource.default.connectionString"
value="Server=SVSQL2008;Database=QuartzNet1;Trusted_Connection=True;" />
<add key="quartz.dataSource.default.provider" value="SqlServer-20" />
</quartz>
There are few things to keep in mind depending if you're hosting Quartz.net in a web application or a service or winform app.
The best approach is to create SchedulerFactory and Scheduler as singleton.
You can gather some more infos here.
UPDATE:
First of all you have to create Quartz.net tables (see Step 1) and then you'll have to create a few indexes for optiomization (see bottom of the page).
Since you're going to submit your jobs using the web app but you're not using that app for the quartz.net events (triggers) you don't need to start the scheduler.
There are few steps to follow on this side:
you have to change the thread pool type to ZeroSizeThreadPool
<add key="quartz.threadPool.type"
value="Quartz.Simpl.ZeroSizeThreadPool, Quartz" />
and you have to define your StdSchedulerFactory and Scheduler singleton. You can start during the application (asp.net) bootstrap.
You're never going to start the Scheduler (your windows service is going to use that).
Another thing to remember is you're going to need share your job between your web and your windows service, so it would be better to keep it in a separate assembly.
You mentioned you're storing some infos in one of your table.
You still need to have to submit your jobs and trigger which will be persisted in Quartz.net tables.
Best Answer
Your trigger creation should be like this:
you can use these options:
You can find a good explanation here.