问题
Let us say I have prepared my Quartz.NET as a Windows service and it is currently being run (with an ADOJobStore
running on Sqlite
). I need to take control of this service on my Windows application so I can stop it, start it, add and remove jobs from it, etc. How can I get an instance of this scheduler?
Sorry if it sounds like a simple question for you, but the documentation on Quartz.NET seems nowhere near enough. There are only a few people who know about it and they already have their lives to live.
Update: quartz.config file of my service
# 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
The code I am using on my program to get the scheduler:
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();
My service is installed and is in Started state and it is log on as a "Local System Account" and it is able interact with the desktop.
回答1:
Your service can expose the scheduler by modifying the config file:
<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" />
Your Windows app can then accesss it with the appropriate settings:
//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();
The quartz.net master contains really good examples that you won't find in the documentation.
回答2:
Starting and stopping the Windows service is not related to Quartz. There seems to be a .NET API for that, but I'm not familiar with it.
As for adding and removing jobs. You won't get the instance of the Windows service's scheduler. There are two ways to work around it.
- Define a WCF contract and host a WCF service in your Windows service. It's pretty straightforward. You don't need IIS nor HTTP. I recommend the TCP binding in this case.
- Since you're already using a ADO job store, you can set up both Windows app and Windows service as a Quartz cluster:
Add
<add key="quartz.jobStore.clustered" value="true"/>
to both app and web configs. If I remember correctly, no additional code is required. Additionally you prevent the Windows app form executing a job by setting up a zero-size thread pool:
<add key="quartz.threadPool.type" value="Quartz.Simpl.ZeroSizeThreadPool, Quartz"/>
Now, you instantiate a scheduler in your Windows app and use it to add and remove jobs. The jobs will be stored in the ADO job store and picked up by the Windows service. Both app and service must have the same ADO job setore configured, obviously, and the Windows app must have access to the sqlite db.
One more thing. Using the second approach you won't be able to interrupt a running job form the Windows app.
来源:https://stackoverflow.com/questions/26480787/get-an-instance-of-the-scheduler-that-is-being-run-on-a-windows-service