We have a Quartz.Net installation that runs as a Windows service. This is working fine. We also have an ASP.Net application that adds / edits tasks and controls tasks. Sometimes we get an error in an ASP.Net application. Errors either "Scheduler has been turned off." or "A scheduler named" JOB_SCHEDULER_NAME "already exists."
If you refresh the page, it works fine. I was able to recreate the problem by quickly opening multiple instances of the same page again and again. So my current theory is that the way to get an instance of Scheduler is not thread safe.
An example is a simplified version of how we get information about work:
var schedulerFactory = new StdSchedulerFactory();
var scheduler = schedulerFactory.GetScheduler();
var jobDetail = scheduler.GetJobDetail("SomeJobName", "SomeJobGroup");
This is done when the page is loaded in an ASP.Net application.
ASP.Net configuration setup:
<quartz>
<add key="quartz.scheduler.instanceName" value="COMPANY_NAME_JobScheduler" />
<add key="quartz.scheduler.instanceId" value="Provider.DEV" />
<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.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz " />
<add key="quartz.dataSource.default.connectionString" value="server=PROD_SQL_SERVER;uid=SQL_USER;pwd=SQL_PASSWORD;database=Scheduler" />
<add key="quartz.dataSource.default.provider" value="SqlServer-20" />
</quartz>
The Windows service initializes the scheduler as follows:
var schedulerFactory = new StdSchedulerFactory();
var scheduler = schedulerFactory.GetScheduler();
Windows Service Configuration:
<quartz>
<add key="quartz.scheduler.instanceName" value="COMPANY_NAME_JobScheduler" />
<add key="quartz.scheduler.instanceId" value="Service.PROD" />
<add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz" />
<add key="quartz.threadPool.threadCount" value="10" />
<add key="quartz.threadPool.threadPriority" value="2" />
<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.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz " />
<add key="quartz.dataSource.default.connectionString" value="server=PROD_SQL_SERVER;uid=SQL_USER;pwd=SQL_PASSWORD;database=Scheduler" />
<add key="quartz.dataSource.default.provider" value="SqlServer-20" />
</quartz>
Is there a better way to “request” a scheduler?
Edit: Added additional configuration information