Quartz.NET远程调度 - 调度程序已存在。

4
我正在创建一个应用程序,该应用程序使用Quartz.NET,该程序用于Windows服务中。还有一个用ASP.NET编写的管理后端,管理员可以在其中添加作业并监视调度程序的状态。然而,我在ASP.NET后端遇到了问题。
连接是在Global.asax文件中进行的,起初似乎工作正常-当用户登录主仪表板时,它可以正常工作。问题出现在用户单击不同页面时,它会提示调度程序“schedService”已经存在。
以下是我的Windows服务代码:
NameValueCollection properties = new NameValueCollection();

properties["quartz.scheduler.instanceName"] = "schedService";
properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
properties["quartz.threadPool.threadCount"] = threadcount;
properties["quartz.threadPool.threadPriority"] = "Normal";
properties["quartz.jobStore.misfireThreshold"] = "60000";
properties["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz";
properties["quartz.jobStore.useProperties"] = "false";
properties["quartz.jobStore.dataSource"] = "default";
properties["quartz.jobStore.tablePrefix"] = "QRTZ_";

//
properties["quartz.scheduler.exporter.type"] = "Quartz.Simpl.RemotingSchedulerExporter, Quartz";
properties["quartz.scheduler.exporter.port"] = "555";
properties["quartz.scheduler.exporter.bindName"] = "QuartzScheduler";
properties["quartz.scheduler.exporter.channelType"] = "tcp";

//
// if running MS SQL Server we need thisl
properties["quartz.jobStore.lockHandler.type"] = "Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz";

// config file
properties["quartz.dataSource.default.connectionString"] = connection;
properties["quartz.dataSource.default.provider"] = "SqlServer-20";

ISchedulerFactory schedService = new StdSchedulerFactory(properties);
IScheduler sched = schedService.GetScheduler();

ASP.NET Global.asax 代码:

public static IScheduler Sched()
{
    NameValueCollection properties = new NameValueCollection();

    properties["quartz.scheduler.instanceName"] = "schedMaintenanceService";

    properties["quartz.scheduler.proxy"] = "true";
    properties["quartz.scheduler.proxy.address"] = "tcp://localhost:555/QuartzScheduler";

    ISchedulerFactory sf = new StdSchedulerFactory(properties);
    IScheduler sched = sf.GetScheduler();
    return sched;
}

然后我在每个ASP.NET页面中使用这个:

public static IScheduler sched = Project.Global.Sched();
3个回答

2

你应该将IScheduler编写为单例模式


谢谢 - 但我该如何做呢?我在网上找到了一些代码,但这是放在客户端还是服务器端,我该如何使用它呢? - Chris
1
你应该将调度器工厂和调度器作为静态类变量移动到Global.asax中,并仅在应用程序启动时初始化它们。 - Marko Lahma
1
要注意应用程序的回收和调度程序被破坏的情况。 - dubs
我也遇到了类似的问题。你能解释一下为什么需要将Ischeduler移动到单例类中吗?在我的应用程序中,我每天需要创建数千个作业,我有点担心对单例类的负载。 - Brainchild
每个人都说你应该使用Singleton,但我找不到一个解决方案。我已经使用了Tarun Arora的解决方案(http://bit.ly/1xuVys0),但我仍然收到相同的错误。这是一个声称已经在使用singleton的解决方案。 - disasterkid

0

我曾经遇到过“调度程序已存在”的类似问题。我创建了一个单例类,然后成功解决了这个问题。

如果有人需要,这是单例模式的代码。锁的作用是为了避免之前出现的多个线程同时获取同一实例的问题。

using Quartz;
using Quartz.Impl;

namespace MyProject.CommonObjects.Utilities
{
  public static class QuartzFactory
  {
    private static object _locker = new object();
    private static IScheduler _schedulerInstance;

    public static IScheduler SchedulerInstance
    {
      get
      {
        lock (_locker)
        {
          if (_schedulerInstance == null)
            _schedulerInstance = StdSchedulerFactory.GetDefaultScheduler();

          return _schedulerInstance;
        }
      }
    }
  }
}

0
我找到了另一个解决方案。通过为每个调度程序提供不同的名称,我能够解决这个问题。我认为这比单例模式更好。
  NameValueCollection properties = new NameValueCollection
  {
    [StdSchedulerFactory.PropertySchedulerInstanceName] = "MyNewScheduler1"
  };
  StdSchedulerFactory fac = new StdSchedulerFactory(properties);
  _scheduler = fac.GetScheduler();
  _scheduler.Start();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接