我一直在努力让这项工作工作几天。我试图使用quartz调度程序在我的主窗体上触发一个事件,从中可以调用一个方法。我的主要表格上的代码如下:
void StartSchedule()
{
string AuctionTime = "0 0 0 ? * MON-FRI *";
JobKey jobkey = new JobKey("Auction", "G");
IJobDetail job = JobBuilder.Create<AuctionJob>()
.WithIdentity(jobkey)
.Build();
CronScheduleBuilder csb = CronScheduleBuilder.CronSchedule(new CronExpression(AuctionTime)).InTimeZone(TimeZoneInfo.Local);
ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()
.WithIdentity("Auction-Trigger", "G")
.WithSchedule(csb)
.Build();
// Create listener
JobListener auctionListener = new JobListener();
auctionListener.JobExecutedHandler += new EventHandler(SendAuctionOrders);
IMatcher<JobKey> matcher = KeyMatcher<JobKey>.KeyEquals(jobkey);
_scheduler.ListenerManager.AddJobListener(auctionlistener, matcher);
// Add to scheduler
DateTimeOffset ft = _scheduler.ScheduleJob(job, trigger);
LogEvent(job.Key + " scheduled at: " + ft.ToLocalTime());
jobkey = new JobKey("Auction2", "G");
IJobDetail job = JobBuilder.Create<AuctionJob>()
.WithIdentity(jobkey)
.Build();
csb = CronScheduleBuilder.CronSchedule(new CronExpression(AuctionTime)).InTimeZone(TimeZoneInfo.Local);
ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()
.WithIdentity("Auction-Trigger", "G")
.WithSchedule(csb)
.Build();
// Create listener
JobListener auction2Listener = new JobListener();
auction2Listener.JobExecutedHandler += new EventHandler(SendAuctionOrders);
IMatcher<JobKey> matcher = KeyMatcher<JobKey>.KeyEquals(jobkey);
_scheduler.ListenerManager.AddJobListener(auction2listener, matcher);
// Add to scheduler
ft = _scheduler.ScheduleJob(job, trigger);
LogEvent(job.Key + " scheduled at: " + ft.ToLocalTime());
_scheduler.Start();
}
void SendAuctionOrders()
{
// Do something
}
AuctionJob类看起来像这样:
public class AuctionJob : IJob
{
public void Execute(IJobExecutionContext context)
{
// Empty
Console.WriteLine("auction exec");
}
}
虽然工作听众看起来像这样:
public class JobListener : IJobListener
{
private static readonly ILog logger = LogManager.GetLogger(typeof(JobListener));
public event EventHandler JobExecutedHandler;
public void JobExecutionVetoed(IJobExecutionContext context)
{
logger.Info("JobExecutionVetoed");
}
public void JobToBeExecuted(IJobExecutionContext context)
{
logger.Info("JobToBeExecuted");
}
public void JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException)
{
// Raise the event on executed
OnJobExecuted(EventArgs.Empty);
logger.Info("JobWasExecuted");
}
public string Name
{
get
{
return "JobListener";
}
}
// Event raiser
protected virtual void OnJobExecuted(EventArgs args)
{
// This code will prevent IllegalThreadContext exceptions
EventHandler jobExecHandler = JobExecutedHandler;
if (jobExecHandler != null)
{
ISynchronizeInvoke target = jobExecHandler.Target as ISynchronizeInvoke;
if (target != null && target.InvokeRequired)
{
target.Invoke(jobExecHandler, new object[] { this, args });
}
else
{
jobExecHandler(this, args);
}
}
}
}
当作业被触发时,作业被执行(控制台打印“拍卖执行”)但是作业监听器的JobWasExecuted不会接收它。任何人都可以帮我这个吗?
其他问题:还有另一种方法来调用主窗体的方法吗?此外,作业监听器类是否会持续整个应用程序(理论上不会关闭)。感谢。
答案 0 :(得分:4)
问题解决了。实现IJobListener类时,Name属性受到保护,并且在添加到ListenerManager时,它会覆盖前一个条目。 Trick是在实例化JobListener类并将其添加到:
时添加自定义字符串public string Name
{
get
{
return instanceName + "JobListener";
}
}
答案 1 :(得分:0)
今天我碰到了类似的东西,我的(log4net)调试行没有在JobWasExecuted方法中输出任何内容,即使JobToBeExecuted中的类似行正在工作。在敲打它大约两个小时后,我通过在我的工作成功完成后提出自定义异常来破坏它。 (&#34; hack&#34;部分必须提出异常才能让JobWasExecuted在我真正想要获得最终工作状态时做出反应。)
我想如果我这样做是为了一个非平凡的项目我只是让我的工作把消息放到一个队列上(并观察那个),我可能会错过一些东西我应该在出去筹集活动的路上设置我的工作,但我仍然发现Quartz.NET世界的这一部分非常混乱。
答案 2 :(得分:0)
我的情况很相似,但有不同的原因 - 我想在这里分享一下,以防其他人遇到同样的问题。事件和听众似乎没有被解雇。我正在动态创建作业/触发器,从数据库中提取触发器启动时间。问题是虽然我从数据库中提取的日期时间是UTC,但在C#中使用时它没有被标记为UTC(而是本地)。这些工作正在按计划进行,但未来9个小时,我预计他们会在一分钟内开火。将日期时间标记为UTC固定为:
DateTime NextExecutionStartDate = DateTime.SpecifyKind(myDBObject.NextExecutionStartDate, DateTimeKind.Utc);
...Trigger.StartAt(NextExecutionStartDate)
而不是
...Trigger.StartAt(myDBObject.NextExecutionStartDate)