我在Microsoft Bot Framework的应用程序中使用Quartz.NET。我在本地计算机上调试它(尽管数据库仍然在Azure上)。
出于某种原因,所有工作都会失败并且他们不会再次开火,即使我尝试了各种各样的.WithMisfire ......选项。
我将工作设置为每15-20秒运行一次以进行测试。我在我的工作类中的Execute()的第一行设置了一个断点,但它从未到达那一点。因此,所有作业都失败,甚至没有达到Execute()。
我可以看到使用TRIGGER_STATE = WAITING
在数据库中创建的作业和触发器。在达到指定的执行时间后,状态将更改为ERROR
。
这是启动调度程序的代码:
public static IScheduler StartAndGetScheduler()
{
NameValueCollection properties = new NameValueCollection();
properties["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz";
properties["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz";
properties["quartz.jobStore.tablePrefix"] = "QRTZ_";
properties["quartz.jobStore.dataSource"] = "default";
properties["quartz.dataSource.default.connectionString"] = "Server=*************.database.windows.net,1433;Initial Catalog=*************;" +
"Persist Security Info=False;User ID=***********;Password=**********;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;";
properties["quartz.dataSource.default.provider"] = "SqlServer-20";
properties["quartz.jobStore.useProperties"] = "true";
properties["quartz.jobStore.lockHandler.type"] = "Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz";
properties["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz";
ISchedulerFactory sf = new StdSchedulerFactory(properties);
scheduler = sf.GetScheduler();
scheduler.Start();
return scheduler;
}
这是安排作业(用于测试)的代码:
try {
Random rnd = new Random();
int dice = rnd.Next(1, 1000);
string jobName = "job719-" + dice.ToString();
LogSchedulerStatus(scheduler, activity);
IJobDetail job = JobBuilder.Create<BotSchedulerJob>()
.WithIdentity(jobName, "group1")
.Build();
currentJob = job;
int dice2 = rnd.Next(1, 1000);
string triggerName = "trigger719-" + dice2.ToString();
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity(triggerName, "group1")
.StartAt(Quartz.DateBuilder.FutureDate(15, IntervalUnit.Second))
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(20)
.WithRepeatCount(2)
.WithMisfireHandlingInstructionNowWithRemainingCount())
.Build();
scheduler.ScheduleJob(job, trigger);
LogSchedulerStatus(scheduler, activity);
}
// no exceptions - all works fine, jobs are in the database
catch (Exception ex)
{
SendReplyToUser(ex.Message + "\n\n" + ex.StackTrace + "\n\n", activity);
}
这就是工作本身:
public class BotSchedulerJob : IJob
{
public void Execute(IJobExecutionContext context)
{
//breakpoint here never reached in debugger
var connector = new ConnectorClient(new Uri("http://localhost:9000/"));
IMessageActivity newMessage = Activity.CreateMessageActivity();
newMessage.Type = ActivityTypes.Message;
newMessage.From = new ChannelAccount("********");
newMessage.Conversation = new ConversationAccount(false, "8a684db8");
newMessage.Recipient = new ChannelAccount("********");
newMessage.Text = "This is a reminder.";
connector.Conversations.SendToConversation((Activity)newMessage);
}
}
在我尝试安排作业后,日志中的最后几行是:
Exception thrown: 'System.FormatException' in mscorlib.dll
Exception thrown: 'Quartz.JobPersistenceException' in Quartz.dll
Exception thrown: 'Quartz.JobPersistenceException' in Quartz.dll
Exception thrown: 'Quartz.JobPersistenceException' in Quartz.dll
Exception thrown: 'Quartz.JobPersistenceException' in Quartz.dll
Exception thrown: 'Quartz.JobPersistenceException' in Quartz.dll
Exception thrown: 'Quartz.JobPersistenceException' in Quartz.dll
Exception thrown: 'Quartz.JobPersistenceException' in mscorlib.dll
最后,如果我将Quartz配置为使用RAMJobStore,它可以正常工作并成功触发作业。