获取在Windows服务上运行的调度程序实例

3
假设我已经将Quartz.NET准备好作为Windows服务,并且它目前正在运行(使用在Sqlite上运行的ADOJobStore)。我需要在我的Windows应用程序中控制此服务,以便我可以停止它,启动它,添加和删除作业等。我该如何获取此调度程序的实例?
如果对您来说这听起来像一个简单的问题,那么很抱歉,因为Quartz.NET的文档似乎远远不够。只有少数人知道它,而他们已经有自己的生活。
更新:我的服务的quartz.config文件
# You can configure your scheduler in either <quartz> configuration section
# or in quartz properties file
# Configuration section has precedence

quartz.threadPool.type = Quartz.Simpl.SimpleThreadPool, Quartz
quartz.threadPool.threadCount = 10
quartz.threadPool.threadPriority = Normal

# job initialization plugin handles our xml reading, without it defaults are used
quartz.plugin.xml.type = Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz
quartz.plugin.xml.fileNames = ~/quartz_jobs.xml

quartz.scheduler.exporter.type = Quartz.Simpl.RemotingSchedulerExporter, Quartz
quartz.scheduler.exporter.port = 555
quartz.scheduler.exporter.bindName = QuartzScheduler
quartz.scheduler.exporter.channelType = tcp
quartz.scheduler.exporter.channelName = httpQuartz

我正在使用的程序代码以获取调度器:
NameValueCollection properties = new NameValueCollection();
properties["quartz.scheduler.instanceName"] = "RemoteClient";

// set thread pool info
properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
properties["quartz.threadPool.threadCount"] = "10";
properties["quartz.threadPool.threadPriority"] = "Normal";

// set remoting expoter
properties["quartz.scheduler.proxy"] = "true";
properties["quartz.scheduler.proxy.address"] = "tcp://127.0.0.1:555/QuartzScheduler";

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

我的服务已安装并处于启动状态,它以“本地系统帐户”身份登录,并能够与桌面交互。

2个回答

5

您的服务可以通过修改配置文件来公开调度程序:

<add key="quartz.scheduler.exporter.type" value="Quartz.Simpl.RemotingSchedulerExporter, Quartz" />
<add key="quartz.scheduler.exporter.port" value="555" />
<add key="quartz.scheduler.exporter.bindName" value="QuartzScheduler" />
<add key="quartz.scheduler.exporter.channelType" value="tcp" />
<add key="quartz.scheduler.exporter.channelName" value="httpQuartz" />

你的Windows应用程序可以通过适当的设置访问它:

        //you can put these in a config file too.
        NameValueCollection properties = new NameValueCollection();
        properties["quartz.scheduler.instanceName"] = "RemoteClient";

        // set thread pool info
        properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
        properties["quartz.threadPool.threadCount"] = "5";
        properties["quartz.threadPool.threadPriority"] = "Normal";

        // set remoting expoter
        properties["quartz.scheduler.proxy"] = "true";
        properties["quartz.scheduler.proxy.address"] = "tcp://127.0.0.1:555/QuartzScheduler";

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

Quartz.net的主页提供了非常好的示例,这些示例在文档中是找不到的。


我正在使用你的解决方案。我已经安装了我的服务器并且它正在运行。但是当我尝试像你说的那样获取调度程序实例时,我几乎在我的调度程序的所有属性上都会收到这个消息:"函数评估需要所有线程运行"。 - disasterkid
我的服务也应该有一个“RemoteClient”的实例名称吗? - disasterkid
我现在已经更新了我的问题,并提供了我在两端使用的代码。 - disasterkid
那显然不是石英问题,我正在接收所有当前运行的作业,这太棒了。 - disasterkid

2

启动和停止Windows服务与Quartz无关。似乎有一个.NET API可以实现,但我不熟悉它。

至于添加和删除作业。您无法获得Windows服务调度程序的实例。有两种解决方法:

  1. 定义WCF合同并在Windows服务中托管WCF服务。这相当简单。您不需要IIS或HTTP。在这种情况下,我推荐使用TCP绑定。
  2. 由于您已经使用了ADO作业存储,因此可以将Windows应用程序和Windows服务设置为Quartz集群:

添加

<add key="quartz.jobStore.clustered" value="true"/>

将以下文本翻译成中文:

适用于应用程序和Web配置。如果我没记错的话,不需要额外的代码。此外,您可以通过设置零大小线程池来防止Windows应用程序执行作业:

<add key="quartz.threadPool.type" value="Quartz.Simpl.ZeroSizeThreadPool, Quartz"/>

现在,您可以在 Windows 应用程序中实例化一个调度器,并使用它来添加和删除作业。这些作业将存储在 ADO 作业存储中,并由 Windows 服务接收。显然,应用程序和服务必须配置相同的 ADO 作业存储,并且 Windows 应用程序必须能够访问 SQLite 数据库。
还有一件事。使用第二种方法,您将无法从 Windows 应用程序中中断正在运行的作业。

...或者您可以使用Quartz内置的远程调用,这是我之前不知道的 :). 正如Circular Reference所建议的。 - Rafał Rutkowski

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