";调度程序已存在问题“;持续存在
本文关键字:存在 问题 quot 调度程序 | 更新日期: 2023-09-27 18:27:42
即使我使用了Tarun Arora的解决方案
名为xxx的计划程序已存在。
问题,我仍然得到相同的错误。这是他的解决方案,我认为他已经正确地实现了Singleton模式:
public class Scheduler
{
public readonly IScheduler Instance;
public string Address { get; private set; }
public string JobName { get; set; }
public string JobGroup { get; set; }
public int Priority { get; set; }
public string CronExpression { get; set; }
private readonly ISchedulerFactory _schedulerFactory;
public Scheduler(string server, int port, string scheduler)
{
Address = string.Format("tcp://{0}:{1}/{2}", server, port, scheduler);
_schedulerFactory = new StdSchedulerFactory(GetProperties(Address));
try
{
Instance = _schedulerFactory.GetScheduler();
if (!Instance.IsStarted)
Instance.Start();
}
catch (SchedulerException ex)
{
throw new Exception(string.Format("Failed: {0}", ex.Message));
}
}
private static NameValueCollection GetProperties(string address)
{
var properties = new NameValueCollection();
properties["quartz.scheduler.instanceName"] = "ServerScheduler";
properties["quartz.scheduler.proxy"] = "true";
properties["quartz.threadPool.threadCount"] = "0";
properties["quartz.scheduler.proxy.address"] = address;
return properties;
}
public IScheduler GetScheduler()
{
return Instance;
}
}
我必须承认,我没有使用他说的最后一部分
如果你想调用Scheduler,那么你应该使用一些东西就像下面的代码示例…
public SchedulerMetaData GetMetaData()
{
var scheduler = new Scheduler("ServerName", Convert.ToInt32("PortNumber"), "Scheduler"));
return scheduler.GetMetaData();
}
这就是我在应用程序中调用调度器的方式:
IScheduler sched = new Scheduler(logger, "127.0.0.1", 555, "QuartzScheduler").Instance;
IJobDetail postbagjob = null;
ITrigger postbagJobTrigger = null;
try
{
postbagjob = JobBuilder.Create<PostbagJob>()
.WithIdentity(jobName, jobGroup)
.UsingJobData("CampaignId", campaignId.ToString())
.UsingJobData("CampaignType", campaignType)
.Build();
postbagJobTrigger = (ICronTrigger)TriggerBuilder.Create()
.WithIdentity(triggerName, triggerGroup)
.WithCronSchedule(cron)
.StartAt(DateTime.Now)
.Build();
}
catch (SchedulerException ex)
{
MsgBox.Show(ex.Message);
}
第一次添加作业时它有效,但第二次调用它时,sched
变为null
。
我已经测试了该实现,它似乎可以工作
你的解决方案中一定有其他东西阻碍了事情的正常运行。
您确定在服务器中运行的作业是PostbagJob
吗?
我建议您检查一下服务器的配置。确保你有这样的东西:
<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"/>
关于cron触发器,您能告诉我们什么?你能发布cron表达式吗
你为什么不试着把它改成一个简单的触发器,看看它是如何工作的:
postbagJobTrigger = (ISimpleTrigger)TriggerBuilder.Create()
.WithIdentity("SampleTrigger", "QUARTZGROUP")
.WithSimpleSchedule(x => x.WithIntervalInSeconds(2).RepeatForever())
.StartNow()
.Build();
您应该做的另一件事是在服务器和客户端之间与作业共享程序集,以便它们具有相同的签名。
我对Scheduler
类做了一些更改。你可以在这里找到最终结果。
注意:
要运行服务器和客户端,请确保在解决方案中配置了多个启动项目(右键单击解决方案)。
更新:
一个更好的方法是这样创建一个单例类:
public sealed class QuartzScheduler
{
private static QuartzScheduler instance = null;
private static readonly object padlock = new object();
private readonly ISchedulerFactory SchedulerFactory = null;
private readonly IScheduler Scheduler = null;
QuartzScheduler()
{
this.SchedulerFactory = new StdSchedulerFactory();
this.Scheduler = this.SchedulerFactory.GetScheduler();
}
public static IScheduler Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new QuartzScheduler();
}
return instance.Scheduler;
}
}
}
}
如果你想阅读更多,你可以在Jon Skeet的博客上找到很多有用的信息
NB:我用了第三个版本
现在,您可以在windows窗体应用程序中简单地使用该对象:
QuartzScheduler.Instance.ScheduleJob(postbagjob, postbagJobTrigger);
仅此而已。
如果您查看我的github回购,您可以找到一个有效的解决方案
我已经在app.config
文件中移动了客户端配置;我想它更容易定制:
<quartz>
<add key="quartz.threadPool.type" value="Quartz.Simpl.ZeroSizeThreadPool, Quartz" />
<add key="quartz.scheduler.instanceName" value="RemoteClient"/>
<add key="quartz.threadPool.threadCount" value="0"/>
<add key="quartz.scheduler.proxy" value="true"/>
<add key="quartz.scheduler.proxy.address" value="tcp://127.0.0.1:555/QuartzScheduler"/>
</quartz>
另一件需要记住的事情是,您的客户端是调度作业,而不是真正运行调度程序,所以您应该将线程池配置为ZeroSizeThreadPool
。
对于Quartz web服务,重新启动应用程序池解决了这个问题。