3

我们有一个作为 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>

有没有更好的方法来“查询”调度程序?

编辑:添加了更多配置信息

4

3 回答 3

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;
 }
于 2010-07-09T19:06:57.950 回答
0

不要让两个调度程序直接连接到数据库,而是尝试让 web 调度程序通过远程连接到服务调度程序。

于 2010-07-09T20:47:08.783 回答
0

正如 Maurice 所指出的,更好的方法可能是使用远程处理。你可以看看这个相关的问题:Use one windows service to execute jobs and two web applications to schedule jobs

于 2012-08-15T14:16:53.383 回答