Quartz.net 同一作业在 asp.net 中同时执行两次



我正在使用石英库版本 2.3.3.0 每天在上午 8 点和下午 4 点的要求时间执行电子邮件发送作业。该网站现已上线,并且在过去两天中一直在正确的时间发送电子邮件。然而,今天早上8点发生了工作被执行了两次,所有电子邮件也被发送了两次。为此,我设置了一个日志表来监视在正确时间执行的电子邮件作业的状态。在今天的日志中,每条记录入两次。我不知道为什么会发生这种情况。下面是我为此功能运行的代码。

作业计划程序.cs

public class JobScheduler
{
public static void Start()
{
IJobDetail emailJob = JobBuilder.Create<EmailJob>()
.WithIdentity("job1")
.Build();
ITrigger trigger = TriggerBuilder.Create().WithDailyTimeIntervalSchedule
(s =>
s.WithIntervalInSeconds(30)
.OnEveryDay()
)
.ForJob(emailJob)
.WithIdentity("trigger1")
.StartNow()
.WithCronSchedule("0 0/1 * * * ?") // Time : Every 1 Minutes job execute
.Build();
ISchedulerFactory sf = new StdSchedulerFactory();
IScheduler sc =  sf.GetScheduler();
sc.ScheduleJob(emailJob, trigger);
sc.Start();
}
}

电子邮件工作.cs

public void Execute(IJobExecutionContext context)
{
//check for date and time of event
//if starttime and date is tomorrow then send reminder email
//if starttime and date is today then send reminder email
string time = DateTime.Now.ToString("h:mm tt");
if (time == "4:00 PM" || time == "8:00 AM")
{
InsertLogMessage("Entring Email Job Execute Function if "+ time);
GetAllBookings();
}
}
private List<int> GetAllBookingsTimes()
{
InsertLogMessage("Getting all booking times when time is " + DateTime.Now.ToShortTimeString());
List<int> lst = new List<int>();
try
{
//Select for upcoming event of today and tomorrow
conn = Database.getInstance();
conn.Open();
cmd = new SqlCommand("ReminderEmails", conn);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@Action", "CheckForReminder");
reader = cmd.ExecuteReader();
while (reader.Read())
{
Times t = new Times();
t.iTimesId = Convert.ToInt32(reader["TimesId"]);
if (!lst.Contains(t.iTimesId))
{
lst.Add(t.iTimesId);
}
}
conn.Close();
}
catch (Exception ex)
{
InsertLogMessage(ex.Message);
}
InsertLogMessage("Returning to Bookings after scheduled times");
return lst;
}
private void GetAllBookings()
{
InsertLogMessage("Getting Booking w.r.t times");
Dictionary<int, List<Booking>> dicofbooking = new Dictionary<int, List<Booking>>();
try {
List<int> timesid = GetAllBookingsTimes();
foreach(var item in timesid)
{
//Get email status confirmation 
bool status = GetEmailStatus(item.ToString());
if (status == false)
{
List<Booking> bookinglst = new List<Booking>();
bookinglst = CheckForReminder().Where(p => p.tTimes.iTimesId == item).ToList();
dicofbooking.Add(item, bookinglst);
}
}
blist = new List<Booking>();
bcclst = new List<string>();
foreach (var item in dicofbooking)
{
foreach (var item1 in item.Value)
{
if (item1.tTimes.dtDateTime.Date == DateTime.Now.Date || item1.tTimes.dtDateTime.Date == DateTime.Now.Date.AddDays(1))
{
//Send email at particular time
if (bcclst.Contains(item1.mMember.strEmailAddress) == false)
{
bcclst.Add(item1.mMember.strEmailAddress);
blist.Add(item1);
}
}
}
if (blist.Count > 0)
{
InsertLogMessage("Sending Email for "+ blist[0].eEvent.strEventTitle + " " + blist[0].tTimes.iTimesId);
if (SendEmail(blist[0]))
{
InsertLogMessage("Email sent successfully for " + blist[0].eEvent.strEventTitle + " " + blist[0].tTimes.iTimesId);
//Set Reminder Email Status to true
UpdateEmailStatus(blist[0].tTimes.iTimesId.ToString());
}
}
blist = new List<Booking>();
bcclst = new List<string>();
}
}
catch (Exception ex)
{
InsertLogMessage(ex.Message);
}

}

此问题是由于在 30 秒和 60 秒等条件下执行触发器。

s.WithIntervalInSeconds(30(

WithCronSchedule("0 0/1 * * * ?"(

在作业上还提到"执行"功能并与其日期时间进行比较,在30s同时可能会被触发。 更改触发器,如下所示

trigger = newTrigger()
.withIdentity("trigger3", "group1")
.withSchedule(cronSchedule("0 0/15 8,16 * * ?"))
.forJob("myJob", "group1")
.build(); 

将作业"执行"功能更改为

public void Execute(IJobExecutionContext context)
{
InsertLogMessage("Entring Email Job Execute Function if "+ time);
GetAllBookings();
}

此触发器每 15 分钟触发一次,但仅在上午 8 点和下午 4 点执行。 无需仔细检查日期时间。

我猜你正在加载配置两次,一次是使用ContextLoaderListener,一次是在DispatcherServlet中,导致重复。检查您的配置。

最新更新