我们有一个作为Windows服务运行的Quartz.Net安装。那运行得很好。我们还有一个ASP.Net应用程序,可以添加/编辑作业和监视作业。我们偶尔会在ASP.Net应用程序中出错。错误是“调度程序已关闭”。或“名为'JOB_SCHEDULER_NAME'的计划程序已存在。”
如果刷新页面,它可以正常工作。我已经能够通过一遍又一遍地快速打开同一页面的多个实例来重新创建问题。所以,我目前的理论是,我们获取调度程序实例的方式不是线程安全的。
举个例子,这里是我们获取工作信息的简化版本:
var schedulerFactory = new StdSchedulerFactory();
var scheduler = schedulerFactory.GetScheduler();
var jobDetail = scheduler.GetJobDetail("SomeJobName", "SomeJobGroup");
在ASP.Net应用程序中加载页面时正在执行此操作。
ASP.Net的配置设置为:
<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>
Windows服务正在初始化调度程序,如下所示:
var schedulerFactory = new StdSchedulerFactory();
var scheduler = schedulerFactory.GetScheduler();
Windows服务配置为:
<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>
有没有更好的方法来“查询”调度程序?
编辑添加了更多配置信息
答案 0 :(得分:5)
我们已将调度程序设置为应用程序中的单例,这为我们解决了问题:
public class MyScheduler
{
static MyScheduler()
{
_schedulerFactory = new StdSchedulerFactory(getProperties());
_scheduler = _schedulerFactory.GetScheduler();
}
public static IScheduler GetScheduler()
{
return _scheduler;
}
private static readonly ISchedulerFactory _schedulerFactory;
private static readonly IScheduler _scheduler;
}
答案 1 :(得分:0)
不要让两个调度程序直接连接到数据库,而是尝试使Web调度程序连接到服务调度程序through remoting。
答案 2 :(得分:0)
正如莫里斯所指出的,更好的方法可能是使用远程处理。您可以查看以下相关问题:Use one windows service to execute jobs and two web applications to schedule jobs