public JobInfo(JobKey id, JobDetailImpl job) { Id = id; Job = job; Triggers = new TriggerInfo[0]; TriggerCount = 0; }
public object Deserialize(global::MongoDB.Bson.IO.BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options) { if (!nominalType.IsAssignableFrom(typeof(JobDetailImpl)) || actualType != typeof(JobDetailImpl)) { var message = string.Format("Can't deserialize a {0} with {1}.", nominalType.FullName, this.GetType().Name); throw new BsonSerializationException(message); } var bsonType = bsonReader.GetCurrentBsonType(); if (bsonType == BsonType.Document) { bsonReader.ReadStartDocument(); BsonSerializer.Deserialize(bsonReader, typeof(JobKey)); bsonReader.ReadString("_t"); Assembly assembly = Assembly.Load(bsonReader.ReadString("_assembly")); Type jobType = assembly.GetType(bsonReader.ReadString("_class")); IJobDetail jobDetail = new JobDetailImpl( bsonReader.ReadString("Name"), bsonReader.ReadString("Group"), jobType, bsonReader.ReadBoolean("RequestRecovery"), bsonReader.ReadBoolean("Durable")); bsonReader.ReadBsonType(); JobDataMap map = (JobDataMap)BsonSerializer.Deserialize(bsonReader, typeof(JobDataMap)); /*bsonReader.ReadBsonType(); string description = (string)BsonSerializer.Deserialize(bsonReader, typeof(string));*/ jobDetail = jobDetail.GetJobBuilder() .UsingJobData(map) /*.WithDescription(description)*/ .Build(); bsonReader.ReadEndDocument(); return jobDetail; } else if (bsonType == BsonType.Null) { bsonReader.ReadNull(); return null; } else { var message = string.Format("Can't deserialize a {0} from BsonType {1}.", nominalType.FullName, bsonType); throw new BsonSerializationException(message); } }
/// <summary> /// 添加一个计划任务(映射程序集指定IJob实现类) /// </summary> /// <typeparam name="T"></typeparam> /// <param name="sysSchedule"></param> /// <returns></returns> public async Task <JobResuleModel> AddScheduleJobAsync(SysSchedule sysSchedule) { var result = new JobResuleModel(); try { if (sysSchedule != null) { JobKey jobKey = new JobKey(sysSchedule.Name, sysSchedule.JobGroup); //if(_scheduler.Result.CheckExists(jobKey)) #region 设置开始时间和结束时间 if (sysSchedule.BeginTime == null) { sysSchedule.BeginTime = DateTime.Now; } DateTimeOffset starRunTime = DateBuilder.NextGivenSecondDate(sysSchedule.BeginTime, 1);//设置开始时间 if (sysSchedule.EndTime == null) { sysSchedule.EndTime = DateTime.MaxValue.AddDays(-1); } DateTimeOffset endRunTime = DateBuilder.NextGivenSecondDate(sysSchedule.EndTime, 1);//设置暂停时间 #endregion #region 通过反射获取程序集类型和类 Assembly assembly = Assembly.Load(new AssemblyName(sysSchedule.AssemblyName)); Type jobType = assembly.GetType(sysSchedule.AssemblyName + "." + sysSchedule.ClassName); #endregion //判断任务调度是否开启 if (!_scheduler.Result.IsStarted) { await StartScheduleAsync(); } //传入反射出来的执行程序集 IJobDetail job = new JobDetailImpl(sysSchedule.Name, sysSchedule.JobGroup, jobType); //Job执行时的参数还有待解决????????????????????? ITrigger trigger; #region 泛型传递 //IJobDetail job = JobBuilder.Create<T>() // .WithIdentity(sysSchedule.Name, sysSchedule.JobGroup) // .Build(); #endregion if (!sysSchedule.Cron.IsNullOrEmpty() && CronExpression.IsValidExpression(sysSchedule.Cron)) { trigger = CreateCronTrigger(sysSchedule); } else { trigger = CreateSimpleTrigger(sysSchedule); } // 告诉Quartz使用我们的触发器来安排作业 await _scheduler.Result.ScheduleJob(job, trigger); await Task.Delay(TimeSpan.FromSeconds(120)); await Console.Out.WriteLineAsync("关闭了调度器!"); await _scheduler.Result.Shutdown(); result.IsSuccess = true; result.Message = $"暂停任务:【{sysSchedule.Name}】成功"; return(result); } else { result.IsSuccess = false; result.Message = $"任务计划不存在:【{sysSchedule.Name}】"; return(result); } } catch (Exception) { throw; } }
/// <summary> /// Adiciona um Job no scheduler do Quartz. /// </summary> /// <param name="jobDetail">Job implementado</param> protected void AddJob(JobDetailImpl jobDetail) { scheduler.AddJob(jobDetail, true); }
/// <summary> /// 添加一个计划任务(映射程序集指定IJob实现类) /// </summary> /// <typeparam name="T"></typeparam> /// <param name="tasksQz"></param> /// <returns></returns> public async Task <MessageModel <string> > AddScheduleJobAsync(TasksQz tasksQz) { var result = new MessageModel <string>(); if (tasksQz != null) { try { JobKey jobKey = new JobKey(tasksQz.Id.ToString(), tasksQz.JobGroup); if (await _scheduler.Result.CheckExists(jobKey)) { result.Success = false; result.Message = $"该任务计划已经在执行:【{tasksQz.JobName}】,请勿重复启动!"; return(result); } #region 通过反射获取程序集类型和类 Assembly assembly = Assembly.Load(new AssemblyName(tasksQz.AssemblyName)); Type jobType = assembly.GetType(tasksQz.AssemblyName + "." + tasksQz.ClassName); //传入反射出来的执行程序集 IJobDetail job = new JobDetailImpl(tasksQz.Id.ToString(), tasksQz.JobGroup, jobType); job.JobDataMap.Add("JobParam", tasksQz.JobParams); //设置参数 #endregion 通过反射获取程序集类型和类 //开启调度器 if (!_scheduler.Result.IsStarted) { await StartScheduleAsync(); } // 创建触发器 ITrigger trigger; #region 创建任务 //IJobDetail job = JobBuilder.Create<JobQuartz>() // .WithIdentity(tasksQz.JobName, tasksQz.JobGroup) // .Build(); #endregion 创建任务 //创建一个触发器 if (tasksQz.Cron != null && CronExpression.IsValidExpression(tasksQz.Cron) && tasksQz.TriggerType == "cron") { trigger = CreateCronTrigger(tasksQz); ((CronTriggerImpl)trigger).MisfireInstruction = MisfireInstruction.CronTrigger.DoNothing; } else { trigger = CreateSimpleTrigger(tasksQz); } //将触发器和任务器绑定到调度器中 await _scheduler.Result.ScheduleJob(job, trigger); result.Success = true; result.Message = $"启动任务:【{tasksQz.JobName}】成功"; return(result); } catch (Exception ex) { result.Success = false; result.Message = $"添加任务异常:【{ex.Message}】"; return(result); } } else { result.Success = false; result.Message = $"任务计划不存在:【{tasksQz.JobName}】"; return(result); } }
/// <summary> /// 添加一个计划任务 /// </summary> /// <param name="tasksQz"></param> /// <returns></returns> public async Task <ApiResult <string> > AddTaskScheduleAsync(Sys_TasksQz tasksQz) { try { JobKey jobKey = new JobKey(tasksQz.ID, tasksQz.JobGroup); if (await _scheduler.Result.CheckExists(jobKey)) { return(new ApiResult <string> { StatusCode = 500, Message = $"该计划任务已经在执行:【{tasksQz.Name}】,请勿重复添加!", }); } #region 设置开始时间和结束时间 tasksQz.BeginTime = tasksQz.BeginTime == null ? DateTime.Now : tasksQz.BeginTime; tasksQz.EndTime = tasksQz.EndTime == null?DateTime.MaxValue.AddDays(-1) : tasksQz.EndTime; DateTimeOffset starRunTime = DateBuilder.NextGivenSecondDate(tasksQz.BeginTime, 1); //设置开始时间 DateTimeOffset endRunTime = DateBuilder.NextGivenSecondDate(tasksQz.EndTime, 1); //设置暂停时间 #endregion #region 通过反射获取程序集类型和类 Assembly assembly = Assembly.Load(new AssemblyName(tasksQz.AssemblyName)); Type jobType = assembly.GetType(tasksQz.AssemblyName + "." + tasksQz.ClassName); #endregion //判断任务调度是否开启 if (!_scheduler.Result.IsStarted) { await StartTaskScheduleAsync(); } //传入反射出来的执行程序集 IJobDetail job = new JobDetailImpl(tasksQz.ID, tasksQz.JobGroup, jobType); job.JobDataMap.Add("JobParam", tasksQz.JobParams); ITrigger trigger; if (tasksQz.Cron != null && CronExpression.IsValidExpression(tasksQz.Cron) && tasksQz.TriggerType > 0) { trigger = CreateCronTrigger(tasksQz); } else { trigger = CreateSimpleTrigger(tasksQz); } // 告诉Quartz使用我们的触发器来安排作业 await _scheduler.Result.ScheduleJob(job, trigger); return(new ApiResult <string> { StatusCode = 200, Message = $"启动计划任务:【{tasksQz.Name}】成功!", }); } catch (Exception ex) { throw ex; } }
public async Task Test(IScheduler scheduler, bool clearJobs, bool scheduleJobs) { try { if (clearJobs) { await scheduler.Clear(); } if (scheduleJobs) { ICalendar cronCalendar = new CronCalendar("0/5 * * * * ?"); ICalendar holidayCalendar = new HolidayCalendar(); // QRTZNET-86 ITrigger t = await scheduler.GetTrigger(new TriggerKey("NonExistingTrigger", "NonExistingGroup")); Assert.IsNull(t); AnnualCalendar cal = new AnnualCalendar(); await scheduler.AddCalendar("annualCalendar", cal, false, true); IOperableTrigger calendarsTrigger = new SimpleTriggerImpl("calendarsTrigger", "test", 20, TimeSpan.FromMilliseconds(5)); calendarsTrigger.CalendarName = "annualCalendar"; JobDetailImpl jd = new JobDetailImpl("testJob", "test", typeof(NoOpJob)); await scheduler.ScheduleJob(jd, calendarsTrigger); // QRTZNET-93 await scheduler.AddCalendar("annualCalendar", cal, true, true); await scheduler.AddCalendar("baseCalendar", new BaseCalendar(), false, true); await scheduler.AddCalendar("cronCalendar", cronCalendar, false, true); await scheduler.AddCalendar("dailyCalendar", new DailyCalendar(DateTime.Now.Date, DateTime.Now.AddMinutes(1)), false, true); await scheduler.AddCalendar("holidayCalendar", holidayCalendar, false, true); await scheduler.AddCalendar("monthlyCalendar", new MonthlyCalendar(), false, true); await scheduler.AddCalendar("weeklyCalendar", new WeeklyCalendar(), false, true); await scheduler.AddCalendar("cronCalendar", cronCalendar, true, true); await scheduler.AddCalendar("holidayCalendar", holidayCalendar, true, true); Assert.IsNotNull(scheduler.GetCalendar("annualCalendar")); JobDetailImpl lonelyJob = new JobDetailImpl("lonelyJob", "lonelyGroup", typeof(SimpleRecoveryJob)); lonelyJob.Durable = true; lonelyJob.RequestsRecovery = true; await scheduler.AddJob(lonelyJob, false); await scheduler.AddJob(lonelyJob, true); string schedId = scheduler.SchedulerInstanceId; int count = 1; JobDetailImpl job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob)); // ask scheduler to re-Execute this job if it was in progress when // the scheduler went down... job.RequestsRecovery = true; IOperableTrigger trigger = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromSeconds(5)); trigger.JobDataMap.Add("key", "value"); trigger.EndTimeUtc = DateTime.UtcNow.AddYears(10); trigger.StartTimeUtc = DateTime.Now.AddMilliseconds(1000L); await scheduler.ScheduleJob(job, trigger); // check that trigger was stored ITrigger persisted = await scheduler.GetTrigger(new TriggerKey("trig_" + count, schedId)); Assert.IsNotNull(persisted); Assert.IsTrue(persisted is SimpleTriggerImpl); count++; job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob)); // ask scheduler to re-Execute this job if it was in progress when // the scheduler went down... job.RequestsRecovery = true; trigger = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromSeconds(5)); trigger.StartTimeUtc = DateTime.Now.AddMilliseconds(2000L); await scheduler.ScheduleJob(job, trigger); count++; job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryStatefulJob)); // ask scheduler to re-Execute this job if it was in progress when // the scheduler went down... job.RequestsRecovery = true; trigger = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromSeconds(3)); trigger.StartTimeUtc = DateTime.Now.AddMilliseconds(1000L); await scheduler.ScheduleJob(job, trigger); count++; job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob)); // ask scheduler to re-Execute this job if it was in progress when // the scheduler went down... job.RequestsRecovery = true; trigger = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromSeconds(4)); trigger.StartTimeUtc = DateTime.Now.AddMilliseconds(1000L); await scheduler.ScheduleJob(job, trigger); count++; job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob)); // ask scheduler to re-Execute this job if it was in progress when // the scheduler went down... job.RequestsRecovery = true; trigger = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromMilliseconds(4500)); await scheduler.ScheduleJob(job, trigger); count++; job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob)); // ask scheduler to re-Execute this job if it was in progress when // the scheduler went down... job.RequestsRecovery = true; IOperableTrigger ct = new CronTriggerImpl("cron_trig_" + count, schedId, "0/10 * * * * ?"); ct.JobDataMap.Add("key", "value"); ct.StartTimeUtc = DateTime.Now.AddMilliseconds(1000); await scheduler.ScheduleJob(job, ct); count++; job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob)); // ask scheduler to re-Execute this job if it was in progress when // the scheduler went down... job.RequestsRecovery = true; var timeZone1 = TimeZoneUtil.FindTimeZoneById("Central European Standard Time"); var timeZone2 = TimeZoneUtil.FindTimeZoneById("Mountain Standard Time"); DailyTimeIntervalTriggerImpl nt = new DailyTimeIntervalTriggerImpl("nth_trig_" + count, schedId, new TimeOfDay(1, 1, 1), new TimeOfDay(23, 30, 0), IntervalUnit.Hour, 1); nt.StartTimeUtc = DateTime.Now.Date.AddMilliseconds(1000); nt.TimeZone = timeZone1; await scheduler.ScheduleJob(job, nt); var loadedNt = (IDailyTimeIntervalTrigger)await scheduler.GetTrigger(nt.Key); Assert.That(loadedNt.TimeZone.Id, Is.EqualTo(timeZone1.Id)); nt.TimeZone = timeZone2; await scheduler.RescheduleJob(nt.Key, nt); loadedNt = (IDailyTimeIntervalTrigger)await scheduler.GetTrigger(nt.Key); Assert.That(loadedNt.TimeZone.Id, Is.EqualTo(timeZone2.Id)); DailyTimeIntervalTriggerImpl nt2 = new DailyTimeIntervalTriggerImpl(); nt2.Key = new TriggerKey("nth_trig2_" + count, schedId); nt2.StartTimeUtc = DateTime.Now.Date.AddMilliseconds(1000); nt2.JobKey = job.Key; await scheduler.ScheduleJob(nt2); // GitHub issue #92 await scheduler.GetTrigger(nt2.Key); // GitHub issue #98 nt2.StartTimeOfDay = new TimeOfDay(1, 2, 3); nt2.EndTimeOfDay = new TimeOfDay(2, 3, 4); await scheduler.UnscheduleJob(nt2.Key); await scheduler.ScheduleJob(nt2); var triggerFromDb = (IDailyTimeIntervalTrigger)await scheduler.GetTrigger(nt2.Key); Assert.That(triggerFromDb.StartTimeOfDay.Hour, Is.EqualTo(1)); Assert.That(triggerFromDb.StartTimeOfDay.Minute, Is.EqualTo(2)); Assert.That(triggerFromDb.StartTimeOfDay.Second, Is.EqualTo(3)); Assert.That(triggerFromDb.EndTimeOfDay.Hour, Is.EqualTo(2)); Assert.That(triggerFromDb.EndTimeOfDay.Minute, Is.EqualTo(3)); Assert.That(triggerFromDb.EndTimeOfDay.Second, Is.EqualTo(4)); job.RequestsRecovery = true; CalendarIntervalTriggerImpl intervalTrigger = new CalendarIntervalTriggerImpl( "calint_trig_" + count, schedId, DateTime.UtcNow.AddMilliseconds(300), DateTime.UtcNow.AddMinutes(1), IntervalUnit.Second, 8); intervalTrigger.JobKey = job.Key; await scheduler.ScheduleJob(intervalTrigger); // custom time zone const string CustomTimeZoneId = "Custom TimeZone"; var webTimezone = TimeZoneInfo.CreateCustomTimeZone( CustomTimeZoneId, TimeSpan.FromMinutes(22), null, null); TimeZoneUtil.CustomResolver = id => { if (id == CustomTimeZoneId) { return(webTimezone); } return(null); }; var customTimeZoneTrigger = TriggerBuilder.Create() .WithIdentity("customTimeZoneTrigger") .WithCronSchedule("0/5 * * * * ?", x => x.InTimeZone(webTimezone)) .StartNow() .ForJob(job) .Build(); await scheduler.ScheduleJob(customTimeZoneTrigger); var loadedCustomTimeZoneTrigger = (ICronTrigger)await scheduler.GetTrigger(customTimeZoneTrigger.Key); Assert.That(loadedCustomTimeZoneTrigger.TimeZone.BaseUtcOffset, Is.EqualTo(TimeSpan.FromMinutes(22))); // bulk operations var info = new Dictionary <IJobDetail, IReadOnlyCollection <ITrigger> >(); IJobDetail detail = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob)); ITrigger simple = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromMilliseconds(4500)); var triggers = new List <ITrigger>(); triggers.Add(simple); info[detail] = triggers; await scheduler.ScheduleJobs(info, true); Assert.IsTrue(await scheduler.CheckExists(detail.Key)); Assert.IsTrue(await scheduler.CheckExists(simple.Key)); // QRTZNET-243 await scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupContains("a").DeepClone()); await scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupEndsWith("a").DeepClone()); await scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupStartsWith("a").DeepClone()); await scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupEquals("a").DeepClone()); await scheduler.GetTriggerKeys(GroupMatcher <TriggerKey> .GroupContains("a").DeepClone()); await scheduler.GetTriggerKeys(GroupMatcher <TriggerKey> .GroupEndsWith("a").DeepClone()); await scheduler.GetTriggerKeys(GroupMatcher <TriggerKey> .GroupStartsWith("a").DeepClone()); await scheduler.GetTriggerKeys(GroupMatcher <TriggerKey> .GroupEquals("a").DeepClone()); await scheduler.Start(); await Task.Delay(TimeSpan.FromSeconds(3)); await scheduler.PauseAll(); await scheduler.ResumeAll(); await scheduler.PauseJob(new JobKey("job_1", schedId)); await scheduler.ResumeJob(new JobKey("job_1", schedId)); await scheduler.PauseJobs(GroupMatcher <JobKey> .GroupEquals(schedId)); await Task.Delay(TimeSpan.FromSeconds(1)); await scheduler.ResumeJobs(GroupMatcher <JobKey> .GroupEquals(schedId)); await scheduler.PauseTrigger(new TriggerKey("trig_2", schedId)); await scheduler.ResumeTrigger(new TriggerKey("trig_2", schedId)); await scheduler.PauseTriggers(GroupMatcher <TriggerKey> .GroupEquals(schedId)); var pausedTriggerGroups = await scheduler.GetPausedTriggerGroups(); Assert.AreEqual(1, pausedTriggerGroups.Count); await Task.Delay(TimeSpan.FromSeconds(3)); await scheduler.ResumeTriggers(GroupMatcher <TriggerKey> .GroupEquals(schedId)); Assert.IsNotNull(scheduler.GetTrigger(new TriggerKey("trig_2", schedId))); Assert.IsNotNull(scheduler.GetJobDetail(new JobKey("job_1", schedId))); Assert.IsNotNull(scheduler.GetMetaData()); Assert.IsNotNull(scheduler.GetCalendar("weeklyCalendar")); var genericjobKey = new JobKey("genericJob", "genericGroup"); GenericJobType.Reset(); var genericJob = JobBuilder.Create <GenericJobType>() .WithIdentity(genericjobKey) .StoreDurably() .Build(); await scheduler.AddJob(genericJob, false); genericJob = await scheduler.GetJobDetail(genericjobKey); Assert.That(genericJob, Is.Not.Null); await scheduler.TriggerJob(genericjobKey); GenericJobType.WaitForTrigger(TimeSpan.FromSeconds(20)); Assert.That(GenericJobType.TriggeredCount, Is.EqualTo(1)); await scheduler.Standby(); CollectionAssert.IsNotEmpty(await scheduler.GetCalendarNames()); CollectionAssert.IsNotEmpty(await scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupEquals(schedId))); CollectionAssert.IsNotEmpty(await scheduler.GetTriggersOfJob(new JobKey("job_2", schedId))); Assert.IsNotNull(scheduler.GetJobDetail(new JobKey("job_2", schedId))); await scheduler.DeleteCalendar("cronCalendar"); await scheduler.DeleteCalendar("holidayCalendar"); await scheduler.DeleteJob(new JobKey("lonelyJob", "lonelyGroup")); await scheduler.DeleteJob(job.Key); await scheduler.GetJobGroupNames(); await scheduler.GetCalendarNames(); await scheduler.GetTriggerGroupNames(); await TestMatchers(scheduler); } } finally { await scheduler.Shutdown(false); } }
public async Task ShouldBeAbleToUseMixedProperties() { 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.dataSource"] = "default"; properties["quartz.jobStore.useProperties"] = false.ToString(); properties["quartz.serializer.type"] = TestConstants.DefaultSerializerType; dbConnectionStrings.TryGetValue("SQLServer", out var connectionString); properties["quartz.dataSource.default.connectionString"] = connectionString; properties["quartz.dataSource.default.provider"] = TestConstants.DefaultSqlServerProvider; ISchedulerFactory sf = new StdSchedulerFactory(properties); IScheduler sched = await sf.GetScheduler(); await sched.Clear(); JobDetailImpl jobWithData = new JobDetailImpl("datajob", "jobgroup", typeof(NoOpJob)); jobWithData.JobDataMap["testkey"] = "testvalue"; IOperableTrigger triggerWithData = new SimpleTriggerImpl("datatrigger", "triggergroup", 20, TimeSpan.FromSeconds(5)); triggerWithData.JobDataMap.Add("testkey", "testvalue"); triggerWithData.EndTimeUtc = DateTime.UtcNow.AddYears(10); triggerWithData.StartTimeUtc = DateTime.Now.AddMilliseconds(1000L); await sched.ScheduleJob(jobWithData, triggerWithData); await sched.Shutdown(); // try again with changing the useproperties against same set of data properties["quartz.jobStore.useProperties"] = true.ToString(); sf = new StdSchedulerFactory(properties); sched = await sf.GetScheduler(); var triggerWithDataFromDb = await sched.GetTrigger(new TriggerKey("datatrigger", "triggergroup")); var jobWithDataFromDb = await sched.GetJobDetail(new JobKey("datajob", "jobgroup")); Assert.That(triggerWithDataFromDb.JobDataMap["testkey"], Is.EqualTo("testvalue")); Assert.That(jobWithDataFromDb.JobDataMap["testkey"], Is.EqualTo("testvalue")); // once more await sched.DeleteJob(jobWithData.Key); await sched.ScheduleJob(jobWithData, triggerWithData); await sched.Shutdown(); properties["quartz.jobStore.useProperties"] = false.ToString(); sf = new StdSchedulerFactory(properties); sched = await sf.GetScheduler(); triggerWithDataFromDb = await sched.GetTrigger(new TriggerKey("datatrigger", "triggergroup")); jobWithDataFromDb = await sched.GetJobDetail(new JobKey("datajob", "jobgroup")); Assert.That(triggerWithDataFromDb.JobDataMap["testkey"], Is.EqualTo("testvalue")); Assert.That(jobWithDataFromDb.JobDataMap["testkey"], Is.EqualTo("testvalue")); }
public void Test(IScheduler scheduler, bool clearJobs, bool scheduleJobs) { try { if (clearJobs) { scheduler.Clear(); } if (scheduleJobs) { ICalendar cronCalendar = new CronCalendar("0/5 * * * * ?"); ICalendar holidayCalendar = new HolidayCalendar(); // QRTZNET-86 ITrigger t = scheduler.GetTrigger(new TriggerKey("NonExistingTrigger", "NonExistingGroup")); Assert.IsNull(t); AnnualCalendar cal = new AnnualCalendar(); scheduler.AddCalendar("annualCalendar", cal, false, true); IOperableTrigger calendarsTrigger = new SimpleTriggerImpl("calendarsTrigger", "test", 20, TimeSpan.FromMilliseconds(5)); calendarsTrigger.CalendarName = "annualCalendar"; JobDetailImpl jd = new JobDetailImpl("testJob", "test", typeof(NoOpJob)); scheduler.ScheduleJob(jd, calendarsTrigger); // QRTZNET-93 scheduler.AddCalendar("annualCalendar", cal, true, true); scheduler.AddCalendar("baseCalendar", new BaseCalendar(), false, true); scheduler.AddCalendar("cronCalendar", cronCalendar, false, true); scheduler.AddCalendar("dailyCalendar", new DailyCalendar(DateTime.Now.Date, DateTime.Now.AddMinutes(1)), false, true); scheduler.AddCalendar("holidayCalendar", holidayCalendar, false, true); scheduler.AddCalendar("monthlyCalendar", new MonthlyCalendar(), false, true); scheduler.AddCalendar("weeklyCalendar", new WeeklyCalendar(), false, true); scheduler.AddCalendar("cronCalendar", cronCalendar, true, true); scheduler.AddCalendar("holidayCalendar", holidayCalendar, true, true); Assert.IsNotNull(scheduler.GetCalendar("annualCalendar")); JobDetailImpl lonelyJob = new JobDetailImpl("lonelyJob", "lonelyGroup", typeof(SimpleRecoveryJob)); lonelyJob.Durable = true; lonelyJob.RequestsRecovery = true; scheduler.AddJob(lonelyJob, false); scheduler.AddJob(lonelyJob, true); string schedId = scheduler.SchedulerInstanceId; int count = 1; JobDetailImpl job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob)); // ask scheduler to re-Execute this job if it was in progress when // the scheduler went down... job.RequestsRecovery = true; IOperableTrigger trigger = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromSeconds(5)); trigger.JobDataMap.Add("key", "value"); trigger.EndTimeUtc = DateTime.UtcNow.AddYears(10); trigger.StartTimeUtc = DateTime.Now.AddMilliseconds(1000L); scheduler.ScheduleJob(job, trigger); // check that trigger was stored ITrigger persisted = scheduler.GetTrigger(new TriggerKey("trig_" + count, schedId)); Assert.IsNotNull(persisted); Assert.IsTrue(persisted is SimpleTriggerImpl); count++; job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob)); // ask scheduler to re-Execute this job if it was in progress when // the scheduler went down... job.RequestsRecovery = (true); trigger = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromSeconds(5)); trigger.StartTimeUtc = (DateTime.Now.AddMilliseconds(2000L)); scheduler.ScheduleJob(job, trigger); count++; job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryStatefulJob)); // ask scheduler to re-Execute this job if it was in progress when // the scheduler went down... job.RequestsRecovery = (true); trigger = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromSeconds(3)); trigger.StartTimeUtc = (DateTime.Now.AddMilliseconds(1000L)); scheduler.ScheduleJob(job, trigger); count++; job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob)); // ask scheduler to re-Execute this job if it was in progress when // the scheduler went down... job.RequestsRecovery = (true); trigger = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromSeconds(4)); trigger.StartTimeUtc = (DateTime.Now.AddMilliseconds(1000L)); scheduler.ScheduleJob(job, trigger); count++; job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob)); // ask scheduler to re-Execute this job if it was in progress when // the scheduler went down... job.RequestsRecovery = (true); trigger = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromMilliseconds(4500)); scheduler.ScheduleJob(job, trigger); count++; job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob)); // ask scheduler to re-Execute this job if it was in progress when // the scheduler went down... job.RequestsRecovery = (true); IOperableTrigger ct = new CronTriggerImpl("cron_trig_" + count, schedId, "0/10 * * * * ?"); ct.JobDataMap.Add("key", "value"); ct.StartTimeUtc = DateTime.Now.AddMilliseconds(1000); scheduler.ScheduleJob(job, ct); count++; job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob)); // ask scheduler to re-Execute this job if it was in progress when // the scheduler went down... job.RequestsRecovery = (true); DailyTimeIntervalTriggerImpl nt = new DailyTimeIntervalTriggerImpl("nth_trig_" + count, schedId, new TimeOfDay(1, 1, 1), new TimeOfDay(23, 30, 0), IntervalUnit.Hour, 1); nt.StartTimeUtc = DateTime.Now.Date.AddMilliseconds(1000); scheduler.ScheduleJob(job, nt); DailyTimeIntervalTriggerImpl nt2 = new DailyTimeIntervalTriggerImpl(); nt2.Key = new TriggerKey("nth_trig2_" + count, schedId); nt2.StartTimeUtc = DateTime.Now.Date.AddMilliseconds(1000); nt2.JobKey = job.Key; scheduler.ScheduleJob(nt2); // GitHub issue #92 scheduler.GetTrigger(nt2.Key); // GitHub issue #98 nt2.StartTimeOfDay = new TimeOfDay(1, 2, 3); nt2.EndTimeOfDay = new TimeOfDay(2, 3, 4); scheduler.UnscheduleJob(nt2.Key); scheduler.ScheduleJob(nt2); var triggerFromDb = (IDailyTimeIntervalTrigger)scheduler.GetTrigger(nt2.Key); Assert.That(triggerFromDb.StartTimeOfDay.Hour, Is.EqualTo(1)); Assert.That(triggerFromDb.StartTimeOfDay.Minute, Is.EqualTo(2)); Assert.That(triggerFromDb.StartTimeOfDay.Second, Is.EqualTo(3)); Assert.That(triggerFromDb.EndTimeOfDay.Hour, Is.EqualTo(2)); Assert.That(triggerFromDb.EndTimeOfDay.Minute, Is.EqualTo(3)); Assert.That(triggerFromDb.EndTimeOfDay.Second, Is.EqualTo(4)); job.RequestsRecovery = (true); CalendarIntervalTriggerImpl intervalTrigger = new CalendarIntervalTriggerImpl( "calint_trig_" + count, schedId, DateTime.UtcNow.AddMilliseconds(300), DateTime.UtcNow.AddMinutes(1), IntervalUnit.Second, 8); intervalTrigger.JobKey = job.Key; scheduler.ScheduleJob(intervalTrigger); // bulk operations var info = new Dictionary <IJobDetail, Collection.ISet <ITrigger> >(); IJobDetail detail = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob)); ITrigger simple = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromMilliseconds(4500)); var triggers = new Collection.HashSet <ITrigger>(); triggers.Add(simple); info[detail] = triggers; scheduler.ScheduleJobs(info, true); Assert.IsTrue(scheduler.CheckExists(detail.Key)); Assert.IsTrue(scheduler.CheckExists(simple.Key)); // QRTZNET-243 scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupContains("a").DeepClone()); scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupEndsWith("a").DeepClone()); scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupStartsWith("a").DeepClone()); scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupEquals("a").DeepClone()); scheduler.GetTriggerKeys(GroupMatcher <TriggerKey> .GroupContains("a").DeepClone()); scheduler.GetTriggerKeys(GroupMatcher <TriggerKey> .GroupEndsWith("a").DeepClone()); scheduler.GetTriggerKeys(GroupMatcher <TriggerKey> .GroupStartsWith("a").DeepClone()); scheduler.GetTriggerKeys(GroupMatcher <TriggerKey> .GroupEquals("a").DeepClone()); scheduler.Start(); Thread.Sleep(TimeSpan.FromSeconds(3)); scheduler.PauseAll(); scheduler.ResumeAll(); scheduler.PauseJob(new JobKey("job_1", schedId)); scheduler.ResumeJob(new JobKey("job_1", schedId)); scheduler.PauseJobs(GroupMatcher <JobKey> .GroupEquals(schedId)); Thread.Sleep(TimeSpan.FromSeconds(1)); scheduler.ResumeJobs(GroupMatcher <JobKey> .GroupEquals(schedId)); scheduler.PauseTrigger(new TriggerKey("trig_2", schedId)); scheduler.ResumeTrigger(new TriggerKey("trig_2", schedId)); scheduler.PauseTriggers(GroupMatcher <TriggerKey> .GroupEquals(schedId)); Assert.AreEqual(1, scheduler.GetPausedTriggerGroups().Count); Thread.Sleep(TimeSpan.FromSeconds(3)); scheduler.ResumeTriggers(GroupMatcher <TriggerKey> .GroupEquals(schedId)); Assert.IsNotNull(scheduler.GetTrigger(new TriggerKey("trig_2", schedId))); Assert.IsNotNull(scheduler.GetJobDetail(new JobKey("job_1", schedId))); Assert.IsNotNull(scheduler.GetMetaData()); Assert.IsNotNull(scheduler.GetCalendar("weeklyCalendar")); Thread.Sleep(TimeSpan.FromSeconds(20)); scheduler.Standby(); CollectionAssert.IsNotEmpty(scheduler.GetCalendarNames()); CollectionAssert.IsNotEmpty(scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupEquals(schedId))); CollectionAssert.IsNotEmpty(scheduler.GetTriggersOfJob(new JobKey("job_2", schedId))); Assert.IsNotNull(scheduler.GetJobDetail(new JobKey("job_2", schedId))); scheduler.DeleteCalendar("cronCalendar"); scheduler.DeleteCalendar("holidayCalendar"); scheduler.DeleteJob(new JobKey("lonelyJob", "lonelyGroup")); scheduler.DeleteJob(job.Key); scheduler.GetJobGroupNames(); scheduler.GetCalendarNames(); scheduler.GetTriggerGroupNames(); } } finally { scheduler.Shutdown(false); } }
/// <summary> /// 添加任务计划 /// </summary> /// <returns></returns> public static async Task <RunResult> AddScheduleJob2(SchedulingTask taskModel) { var status = new RunResult(); try { scheduler = await GetScheduler(); //检查任务是否已存在 var jk = new JobKey(taskModel.TaskName, taskModel.TaskGroupName); //如果不存在 if (!await scheduler.CheckExists(jk)) { //使用Cron表达式计算触发间隔时间 var cronSchedule = taskModel.IntervalTime; Type jobType = Type.GetType(taskModel.TaskClassFullName); // 定义这个工作,并将其绑定到我们的IJob实现类 IJobDetail job = new JobDetailImpl(taskModel.TaskName, taskModel.TaskGroupName, jobType) { Description = taskModel.TaskDescription }; ITrigger trigger = TriggerBuilder.Create() .WithIdentity(taskModel.TriggerName, taskModel.TriggerGroupName) .StartAt((DateTimeOffset)taskModel.StartTime) //指定开始时间 .EndAt((DateTimeOffset)taskModel.EndTime) //指定结束时间 .WithCronSchedule(cronSchedule, action => action.WithMisfireHandlingInstructionDoNothing()) //使用Cron表达式 /* * withMisfireHandlingInstructionDoNothing * ——不触发立即执行 * ——等待下次Cron触发频率到达时刻开始按照Cron频率依次执行 * * withMisfireHandlingInstructionIgnoreMisfires * ——以错过的第一个频率时间立刻开始执行 * ——重做错过的所有频率周期后 * ——当下一次触发频率发生时间大于当前时间后,再按照正常的Cron频率依次执行 * * withMisfireHandlingInstructionFireAndProceed * ——以当前时间为触发频率立刻触发一次执行 * ——然后按照Cron频率依次执行 * */ .ForJob(taskModel.TaskName, taskModel.TaskGroupName) //通过JobKey识别作业 .Build(); // 告诉Quartz使用我们的触发器来安排作业 await scheduler.ScheduleJob(job, trigger); await scheduler.Start(); // await Task.Delay(TimeSpan.FromSeconds(5)); status.Status = 1; status.Msg = "任务计划运行成功"; } else // 如果存在,判断cron表达式是否相同,不同则更新 { var trigger = await scheduler.GetTrigger(new Quartz.TriggerKey(taskModel.TriggerName, taskModel.TriggerGroupName)); var cron = taskModel.IntervalTime; if (trigger != null) { var triggerImpl = trigger as CronTriggerImpl; if (triggerImpl.CronExpressionString != cron) { var jobDetail = await scheduler.GetJobDetail(triggerImpl.JobKey); // var t = jobDetail.GetType(); // JobDetailImpl var jobImpl = jobDetail as Quartz.Impl.JobDetailImpl; var newTrigger = TriggerBuilder.Create() .WithIdentity(taskModel.TriggerName, taskModel.TriggerGroupName) .StartAt(DateTimeOffset.UtcNow) //指定开始时间 .EndAt(taskModel.EndTime) //指定结束时间 .WithCronSchedule(cron, action => action.WithMisfireHandlingInstructionDoNothing()) //使用Cron表达式//第一次启动时不执行 .ForJob(jobDetail) //通过JobKey识别作业 .Build(); await scheduler.RescheduleJob(triggerImpl.Key, newTrigger); var firetime = newTrigger.GetNextFireTimeUtc(); var nexttime = firetime.HasValue ? firetime.Value.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss") : "无"; status.Status = 1; status.Msg = $"调度任务[{taskModel.TaskName}]更新执行计划成功,下次执行时间:{nexttime}"; } else { status.Status = 2; status.Msg = $"调度任务[{taskModel.TaskName}]运行正常"; } } else { status.Status = 2; status.Msg = $"调度任务[{taskModel.TaskName}]运行正常"; } } } catch (Exception ex) { status.Status = 2; status.Msg = "任务计划运行异常,异常信息:" + ex.Message; } return(status); }
/// <summary> /// 添加任务计划 /// </summary> /// <returns></returns> public static async Task <RunResult> AddScheduleJob(SchedulingTask taskModel) { var status = new RunResult(); try { scheduler = await GetScheduler(); //检查任务是否已存在 var jk = new JobKey(taskModel.TaskName, taskModel.TaskGroupName); //如果不存在 if (!await scheduler.CheckExists(jk)) { //使用Cron表达式计算触发间隔时间 var cronSchedule = CronCommon.CronSchedule(taskModel.IntervalTime); Type jobType = Type.GetType(taskModel.TaskClassFullName); // 定义这个工作,并将其绑定到我们的IJob实现类 IJobDetail job = new JobDetailImpl(taskModel.TaskName, taskModel.TaskGroupName, jobType) { Description = taskModel.TaskDescription }; ITrigger trigger = TriggerBuilder.Create() .WithIdentity(taskModel.TriggerName, taskModel.TriggerGroupName) .StartAt((DateTimeOffset)taskModel.StartTime) //指定开始时间 .EndAt((DateTimeOffset)taskModel.EndTime) //指定结束时间 .WithCronSchedule(cronSchedule, action => action.WithMisfireHandlingInstructionDoNothing()) //使用Cron表达式 /* * withMisfireHandlingInstructionDoNothing * ——不触发立即执行 * ——等待下次Cron触发频率到达时刻开始按照Cron频率依次执行 * * withMisfireHandlingInstructionIgnoreMisfires * ——以错过的第一个频率时间立刻开始执行 * ——重做错过的所有频率周期后 * ——当下一次触发频率发生时间大于当前时间后,再按照正常的Cron频率依次执行 * * withMisfireHandlingInstructionFireAndProceed * ——以当前时间为触发频率立刻触发一次执行 * ——然后按照Cron频率依次执行 * */ .ForJob(taskModel.TaskName, taskModel.TaskGroupName) //通过JobKey识别作业 .Build(); // 告诉Quartz使用我们的触发器来安排作业 await scheduler.ScheduleJob(job, trigger); await scheduler.Start(); // await Task.Delay(TimeSpan.FromSeconds(5)); status.Status = 1; status.Msg = "任务计划运行成功"; } else { status.Status = 1; status.Msg = "任务计划运行正常"; } } catch (Exception ex) { status.Status = 2; status.Msg = "任务计划运行异常,异常信息:" + ex.Message; } return(status); }
public static async Task InitHander() { // Grab the Scheduler instance from the Factory NameValueCollection props = new NameValueCollection { { "quartz.serializer.type", "binary" } }; StdSchedulerFactory factory = new StdSchedulerFactory(props); IScheduler scheduler = await factory.GetScheduler(); // try { var configBuilder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("config/ScheduleEntityConfig.json", optional: false, reloadOnChange: true); _configuration = configBuilder.Build(); //从配置信息里面强类型转换 var moduleSettings = new List <ScheduleEntity>(); _configuration.GetSection("ScheduleConfig").Bind(moduleSettings); moduleSettings = moduleSettings.FindAll(c => c.Status == EnumType.JobStatus.已启用); if (moduleSettings == null || moduleSettings.Count < 1) { await Console.Out.WriteLineAsync("没有服务需要启动"); return; } //start scheduler await scheduler.Start(); foreach (var item in moduleSettings) { //定义需要反射的文件 AssemblyName assemblyName = new AssemblyName(item.AssemblyName); //反射出服务 Type jobType = Assembly.Load(assemblyName).GetType(item.JobName); // define the job and tie it to our HelloJob class IJobDetail job = new JobDetailImpl(item.JobName, item.JobGroup, jobType); // 创建触发器 ITrigger trigger; //校验是否正确的执行周期表达式 if (!string.IsNullOrEmpty(item.Cron) && CronExpression.IsValidExpression(item.Cron)) { Console.WriteLine($"成功触发:{item.JobName}服务"); trigger = CreateCronTrigger(item); } else { Console.WriteLine($"服务:{item.JobName},Cron[{item.Cron}]表达式错误"); continue; } // 告诉Quartz使用我们的触发器来安排作业 await scheduler.ScheduleJob(job, trigger); } } catch (SchedulerException se) { Console.WriteLine($"异常错误信息:{se.ToString()}"); //and last shut down the scheduler when you are ready to close your program await scheduler.Shutdown(); } }
public void ManagedTask(TaskSettings settings) { foreach (var setting in settings) { _sched.DeleteJob(new JobKey(setting.JobType, TaskGroup)); if (setting.Enabled) { if (string.IsNullOrEmpty(setting.JobType)) { continue; } var taskType = Type.GetType(setting.JobType); if (taskType == null) { continue; } if (_sched.CheckExists(new JobKey(setting.JobType, TaskGroup))) { continue; } var jobDetail = new JobDetailImpl(setting.JobType, TaskGroup, taskType); jobDetail.JobDataMap[DataMap] = setting; var cronExpression = GetCronString(setting); if (string.IsNullOrEmpty(cronExpression)) { continue; } var trigger = new CronTriggerImpl(setting.JobType, TaskGroup, setting.JobType, TaskGroup, cronExpression); _sched.ScheduleJob(jobDetail, trigger); } } var moduleTasks = AttachedModules.GetModules <IModuleTask>(); foreach (var moduleTask in moduleTasks) { var classInstance = (IModuleTask)Activator.CreateInstance(moduleTask, null); var tasksSettings = classInstance.GetTasks(); foreach (var setting in tasksSettings) { _sched.DeleteJob(new JobKey(setting.JobType, ModuleGroup)); if (setting.Enabled) { var type = Type.GetType(setting.JobType); if (type == null) { continue; } var cronExpression = GetCronString(setting); if (string.IsNullOrEmpty(cronExpression)) { continue; } var jobDetail = new JobDetailImpl(setting.JobType, ModuleGroup, type); jobDetail.JobDataMap[DataMap] = setting; var trigger = new CronTriggerImpl(setting.JobType, ModuleGroup, setting.JobType, ModuleGroup, cronExpression); _sched.ScheduleJob(jobDetail, trigger); } } } }
/// <summary> /// 添加一个计划任务(映射程序集指定IJob实现类) /// </summary> /// <typeparam name="T"></typeparam> /// <param name="tasksQz"></param> /// <returns></returns> public async Task <MessageModel <string> > AddScheduleJobAsync(TasksQz tasksQz) { var result = new MessageModel <string>(); if (tasksQz != null) { try { JobKey jobKey = new JobKey(tasksQz.Id.ToString(), tasksQz.JobGroup); if (await _scheduler.Result.CheckExists(jobKey)) { await this._scheduler.Result.ResumeJob(jobKey); #region triggers方式也通过 //var triggers = await this._scheduler.Result.GetTriggersOfJob(jobKey); //ITrigger triggerHas = triggers?.Where(x => (x as CronTriggerImpl).Name == tasksQz.Id.ToString()).FirstOrDefault(); //if (triggerHas == null) //{ // result.success = false; // result.msg = $"未找到触发器[{tasksQz.Name}]"; // return result; //} //await this._scheduler.Result.ResumeTrigger(triggerHas.Key); #endregion result.success = true; result.msg = $"重复启动!"; return(result); } #region 通过反射获取程序集类型和类 Assembly assembly = Assembly.Load(new AssemblyName(tasksQz.AssemblyName)); Type jobType = assembly.GetType(tasksQz.AssemblyName + "." + tasksQz.ClassName); #endregion //判断任务调度是否开启 if (!_scheduler.Result.IsStarted) { await StartScheduleAsync(); } //传入反射出来的执行程序集 IJobDetail job = new JobDetailImpl(tasksQz.Id.ToString(), tasksQz.JobGroup, jobType); job.JobDataMap.Add("JobParam", tasksQz.JobParams); ITrigger trigger; #region 泛型传递 //IJobDetail job = JobBuilder.Create<T>() // .WithIdentity(sysSchedule.Name, sysSchedule.JobGroup) // .Build(); #endregion if (tasksQz.Cron != null && CronExpression.IsValidExpression(tasksQz.Cron) && tasksQz.TriggerType > 0) { trigger = CreateCronTrigger(tasksQz); } else { trigger = CreateSimpleTrigger(tasksQz); } // 告诉Quartz使用我们的触发器来安排作业 await _scheduler.Result.ScheduleJob(job, trigger); //await Task.Delay(TimeSpan.FromSeconds(120)); //await Console.Out.WriteLineAsync("关闭了调度器!"); //await _scheduler.Result.Shutdown(); result.success = true; result.msg = $"启动任务:【{tasksQz.Name}】成功"; return(result); } catch (Exception ex) { result.success = false; result.msg = $"任务计划异常:【{ex.Message}】"; Console.WriteLine(result.msg); return(result); } } else { result.success = false; result.msg = $"任务计划不存在:【{tasksQz.Name}】"; return(result); } }
static void StoreJobCore(this IScheduler scheduler, JobDetailImpl jobDetail) { jobDetail.Durable = true; scheduler.AddJob(jobDetail, true); }
public void TestSchedulerFactoryObjectWithPlainQuartzObjects() { IJobFactory jobFactory = new AdaptableJobFactory(); TestObject tb = new TestObject("tb", 99); JobDetailImpl jobDetail0 = new JobDetailImpl(); jobDetail0.JobType = typeof(IJob); jobDetail0.Name = ("myJob0"); jobDetail0.Group = (SchedulerConstants.DefaultGroup); jobDetail0.JobDataMap.Add("testObject", tb); Assert.AreEqual(tb, jobDetail0.JobDataMap.Get("testObject")); CronTriggerImpl trigger0 = new CronTriggerImpl(); trigger0.Name = ("myTrigger0"); trigger0.Group = SchedulerConstants.DefaultGroup; trigger0.JobName = "myJob0"; trigger0.JobGroup = SchedulerConstants.DefaultGroup; trigger0.StartTimeUtc = (DateTime.UtcNow); trigger0.CronExpressionString = ("0/1 * * * * ?"); TestMethodInvokingTask task1 = new TestMethodInvokingTask(); MethodInvokingJobDetailFactoryObject mijdfb = new MethodInvokingJobDetailFactoryObject(); mijdfb.Name = ("myJob1"); mijdfb.Group = (SchedulerConstants.DefaultGroup); mijdfb.TargetObject = (task1); mijdfb.TargetMethod = ("doSomething"); mijdfb.AfterPropertiesSet(); IJobDetail jobDetail1 = (IJobDetail)mijdfb.GetObject(); SimpleTriggerImpl trigger1 = new SimpleTriggerImpl(); trigger1.Name = "myTrigger1"; trigger1.Group = SchedulerConstants.DefaultGroup; trigger1.JobName = "myJob1"; trigger1.JobGroup = SchedulerConstants.DefaultGroup; trigger1.StartTimeUtc = (DateTime.UtcNow); trigger1.RepeatCount = (SimpleTriggerImpl.RepeatIndefinitely); trigger1.RepeatInterval = TimeSpan.FromMilliseconds(20); IScheduler scheduler = MockRepository.GenerateMock <IScheduler>(); SchedulerFactoryObject schedulerFactoryObject = new TestSchedulerFactoryObject(scheduler); schedulerFactoryObject.JobFactory = (jobFactory); schedulerFactoryObject.JobDetails = (new IJobDetail[] { jobDetail0, jobDetail1 }); schedulerFactoryObject.Triggers = (new ITrigger[] { trigger0, trigger1 }); try { schedulerFactoryObject.AfterPropertiesSet(); schedulerFactoryObject.Start(); } finally { schedulerFactoryObject.Dispose(); } scheduler.AssertWasCalled(x => x.JobFactory = jobFactory); scheduler.AssertWasCalled(x => x.AddJob(jobDetail0, true)); scheduler.AssertWasCalled(x => x.AddJob(jobDetail1, true)); scheduler.AssertWasCalled(x => x.GetJobDetail(new JobKey("myJob0", SchedulerConstants.DefaultGroup))); scheduler.AssertWasCalled(x => x.GetJobDetail(new JobKey("myJob1", SchedulerConstants.DefaultGroup))); scheduler.AssertWasCalled(x => x.GetTrigger(new TriggerKey("myTrigger0", SchedulerConstants.DefaultGroup))); scheduler.AssertWasCalled(x => x.GetTrigger(new TriggerKey("myTrigger1", SchedulerConstants.DefaultGroup))); }
public static void StoreJob(this IScheduler scheduler, JobDetailImpl jobDetail) { scheduler.StoreJobCore(jobDetail); }
public async Task StressTest() { NameValueCollection properties = new NameValueCollection(); properties["quartz.scheduler.instanceName"] = "TestScheduler"; properties["quartz.scheduler.instanceId"] = "instance_one"; properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz"; properties["quartz.threadPool.threadCount"] = "10"; properties["quartz.serializer.type"] = TestConstants.DefaultSerializerType; properties["quartz.jobStore.misfireThreshold"] = "60000"; properties["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz"; properties["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz"; properties["quartz.jobStore.useProperties"] = "false"; properties["quartz.jobStore.dataSource"] = "default"; properties["quartz.jobStore.tablePrefix"] = "QRTZ_"; properties["quartz.jobStore.clustered"] = "false"; properties["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz"; properties["quartz.dataSource.default.connectionString"] = TestConstants.SqlServerConnectionString; properties["quartz.dataSource.default.provider"] = TestConstants.DefaultSqlServerProvider; // First we must get a reference to a scheduler ISchedulerFactory sf = new StdSchedulerFactory(properties); IScheduler sched = await sf.GetScheduler(); try { await sched.Clear(); JobDetailImpl lonelyJob = new JobDetailImpl("lonelyJob", "lonelyGroup", typeof(SimpleRecoveryJob)); lonelyJob.Durable = true; lonelyJob.RequestsRecovery = true; await sched.AddJob(lonelyJob, false); await sched.AddJob(lonelyJob, true); string schedId = sched.SchedulerInstanceId; JobDetailImpl job = new JobDetailImpl("job_to_use", schedId, typeof(SimpleRecoveryJob)); for (int i = 0; i < 100000; ++i) { IOperableTrigger trigger = new SimpleTriggerImpl("stressing_simple", SimpleTriggerImpl.RepeatIndefinitely, TimeSpan.FromSeconds(1)); trigger.StartTimeUtc = DateTime.Now.AddMilliseconds(i); await sched.ScheduleJob(job, trigger); } for (int i = 0; i < 100000; ++i) { IOperableTrigger ct = new CronTriggerImpl("stressing_cron", "0/1 * * * * ?"); ct.StartTimeUtc = DateTime.Now.AddMilliseconds(i); await sched.ScheduleJob(job, ct); } Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); await sched.Start(); await Task.Delay(TimeSpan.FromMinutes(3)); stopwatch.Stop(); Console.WriteLine("Took: " + stopwatch.Elapsed); } finally { await sched.Shutdown(false); } }
public static void AssignDataMap(this JobDetailImpl jobDetail, ITypeInfo typeInfo, IDataMap jobDataMap) { typeInfo.Members.Where(CanBeMapped()).Each(info => jobDetail.JobDataMap.MapValue(jobDataMap, info)); }
/// <summary> /// 添加一个计划任务(映射程序集指定IJob实现类) /// </summary> /// <typeparam name="T"></typeparam> /// <param name="tasksQz"></param> /// <returns></returns> public async Task <MessageModel <string> > AddScheduleJobAsync(TasksQz tasksQz) { var result = new MessageModel <string>(); if (tasksQz != null) { try { JobKey jobKey = new JobKey(tasksQz.Id.ToString(), tasksQz.JobGroup); if (await _scheduler.Result.CheckExists(jobKey)) { result.success = false; result.msg = $"该任务计划已经在执行:【{tasksQz.Name}】,请勿重复启动!"; return(result); } #region 设置开始时间和结束时间 if (tasksQz.BeginTime == null) { tasksQz.BeginTime = DateTime.Now; } DateTimeOffset starRunTime = DateBuilder.NextGivenSecondDate(tasksQz.BeginTime, 1);//设置开始时间 if (tasksQz.EndTime == null) { tasksQz.EndTime = DateTime.MaxValue.AddDays(-1); } DateTimeOffset endRunTime = DateBuilder.NextGivenSecondDate(tasksQz.EndTime, 1);//设置暂停时间 #endregion #region 通过反射获取程序集类型和类 Assembly assembly = Assembly.Load(new AssemblyName(tasksQz.AssemblyName)); Type jobType = assembly.GetType(tasksQz.AssemblyName + "." + tasksQz.ClassName); #endregion //判断任务调度是否开启 if (!_scheduler.Result.IsStarted) { await StartScheduleAsync(); } //传入反射出来的执行程序集 IJobDetail job = new JobDetailImpl(tasksQz.Id.ToString(), tasksQz.JobGroup, jobType); job.JobDataMap.Add("JobParam", tasksQz.JobParams); ITrigger trigger; #region 泛型传递 //IJobDetail job = JobBuilder.Create<T>() // .WithIdentity(sysSchedule.Name, sysSchedule.JobGroup) // .Build(); #endregion if (tasksQz.Cron != null && CronExpression.IsValidExpression(tasksQz.Cron) && tasksQz.TriggerType > 0) { trigger = CreateCronTrigger(tasksQz); ((CronTriggerImpl)trigger).MisfireInstruction = MisfireInstruction.CronTrigger.DoNothing; } else { trigger = CreateSimpleTrigger(tasksQz); } // 告诉Quartz使用我们的触发器来安排作业 await _scheduler.Result.ScheduleJob(job, trigger); //await Task.Delay(TimeSpan.FromSeconds(120)); //await Console.Out.WriteLineAsync("关闭了调度器!"); //await _scheduler.Result.Shutdown(); result.success = true; result.msg = $"【{tasksQz.Name}】成功"; return(result); } catch (Exception ex) { result.success = false; result.msg = $"任务计划异常:【{ex.Message}】"; return(result); } } else { result.success = false; result.msg = $"任务计划不存在:【{tasksQz?.Name}】"; return(result); } }
public bool PrepareDownload(StreamExtended stream) { string streamUrl; streamUrl = "https://www.twitch.tv/videos/" + stream.streamId; YoutubeDlVideoJson.YoutubeDlVideoInfo youtubeDlVideoInfo = StreamHelpers.GetDownloadQualityUrl(streamUrl, stream.streamerId); string streamDirectory = $"{GlobalConfig.GetGlobalConfig("contentRootPath")}streamers/{stream.streamerId}/vods/{stream.streamId}"; Directory.CreateDirectory(streamDirectory); if (!string.IsNullOrEmpty(stream.thumbnailLocation)) { //todo handle missing thumbnail, maybe use youtubedl generated thumbnail instead DownloadHelpers.DownloadFile( stream.thumbnailLocation.Replace("%{width}", "320").Replace("%{height}", "180"), $"{streamDirectory}/thumbnail.jpg"); } string title = String.IsNullOrEmpty(stream.title) ? "vod" : stream.title; string outputPath = $"{streamDirectory}/{title}.{stream.streamId}"; string dbOutputPath = $"streamers/{stream.streamerId}/vods/{stream.streamId}/{title}.{stream.streamId}.mp4"; //TODO more should be queued, not done immediately IJobDetail job; string triggerIdentity; job = JobBuilder.Create <DownloadStreamJob>() .WithIdentity("StreamDownload" + stream.streamId) .UsingJobData("title", title) .UsingJobData("streamDirectory", streamDirectory) .UsingJobData("formatId", youtubeDlVideoInfo.formatId) .UsingJobData("url", streamUrl) .UsingJobData("isLive", false) .UsingJobData("youtubeDlVideoInfoDuration", youtubeDlVideoInfo.duration) .UsingJobData("retry", true) .RequestRecovery() .Build(); job.JobDataMap.Put("stream", stream); triggerIdentity = $"StreamDownload{stream.streamId}"; /*string jobId = BackgroundJob.Enqueue(() => * DownloadStream(stream, title, streamDirectory, youtubeDlVideoInfo.url, CancellationToken.None, * isLive, youtubeDlVideoInfo.duration));*/ Stream? dbStream; bool downloadChat = false; IJobDetail chatDownloadJob = new JobDetailImpl(); using (var context = new MainDataContext()) { dbStream = context.Streams.FirstOrDefault(item => item.streamId == stream.streamId); if (dbStream != null) { dbStream.streamId = stream.streamId; dbStream.streamerId = stream.streamerId; dbStream.quality = youtubeDlVideoInfo.quality; dbStream.url = youtubeDlVideoInfo.url; dbStream.title = stream.title; dbStream.createdAt = stream.createdAt; dbStream.location = $"streamers/{stream.streamerId}/vods/{stream.streamId}/"; dbStream.fileName = $"{title}.{stream.streamId}.mp4"; dbStream.duration = youtubeDlVideoInfo.duration; dbStream.downloading = true; dbStream.downloadJobId = job.Key.ToString(); } else { downloadChat = true; chatDownloadJob = JobBuilder.Create <ChatDownloadJob>() .WithIdentity("DownloadChat" + stream.streamId) .UsingJobData("streamId", stream.streamId) .UsingJobData("retry", true) .RequestRecovery() .Build(); dbStream = new Stream { streamId = stream.streamId, streamerId = stream.streamerId, quality = youtubeDlVideoInfo.quality, title = stream.title, url = youtubeDlVideoInfo.url, createdAt = stream.createdAt, location = $"streamers/{stream.streamerId}/vods/{stream.streamId}/", fileName = $"{title}.{stream.streamId}.mp4", duration = youtubeDlVideoInfo.duration, downloading = true, chatDownloading = true, downloadJobId = job.Key.ToString(), chatDownloadJobId = chatDownloadJob.Key.ToString() }; // only download chat if this is a new vod context.Add(dbStream); } context.SaveChanges(); } //var chatSchedulerFactory = new StdSchedulerFactory(QuartzSchedulers.SingleThreadScheduler()); var vodSchedulerFactory = new StdSchedulerFactory(QuartzSchedulers.PrimaryScheduler()); //IScheduler chatScheduler = chatSchedulerFactory.GetScheduler().Result; IScheduler vodScheduler = vodSchedulerFactory.GetScheduler().Result; //chatScheduler.Start(); vodScheduler.Start(); ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create() .WithIdentity(triggerIdentity) .StartNow() .Build(); vodScheduler.ScheduleJob(job, trigger); if (downloadChat) { ISimpleTrigger chatDownloadTrigger = (ISimpleTrigger)TriggerBuilder.Create() .WithIdentity("DownloadChat" + stream.streamId) .StartNow() .Build(); vodScheduler.ScheduleJob(chatDownloadJob, chatDownloadTrigger); } //_hubContext.Clients.All.SendAsync("ReceiveMessage", CheckForDownloadingStreams()); return(true); }
/// <summary> /// 把新加的Job添加到调度器 /// </summary> /// <param name="scheduler">调度器</param> /// <param name="jobInfo">Job信息</param> private static async void ManagerJob(IScheduler scheduler, JobInfoEntity jobInfo) { if (CronExpression.IsValidExpression(jobInfo.CronExpression)) { Type type = jobInfo.IsNativeJob ? GetClassInfo(jobInfo.AssemblyName, jobInfo.ClassName) : typeof(HttpJob); if (type != null) { try { IJobDetail job = new JobDetailImpl(jobInfo.Id.ToString(), jobInfo.Id.ToString() + "Group", type); job.JobDataMap.Add("Parameters", jobInfo.JobArgs); job.JobDataMap.Add("JobName", jobInfo.Name); job.JobDataMap.Add("RemoteInfo", new RemoteInfo { JobId = jobInfo.Id, JobName = jobInfo.Name, JobGroup = jobInfo.Group, IsNativeJob = jobInfo.IsNativeJob, RomoteUrl = jobInfo.RomoteUrl }); CronTriggerImpl trigger = new CronTriggerImpl { CronExpressionString = jobInfo.CronExpression, Name = jobInfo.Id.ToString(), Group = $"{jobInfo.Id}TriggerGroup", Description = jobInfo.Description, TimeZone = TimeZoneInfo.Local }; await scheduler.ScheduleJob(job, trigger); } catch (Exception e) { new JobService().InsertLog(new JobLogEntity { JobId = jobInfo.Id, FireTime = DateTime.Now, FireDuration = 0, FireState = FireState.Error, Content = $"{jobInfo.Name}启用失败,异常信息:{e.Message}!", CreateTime = DateTime.Now }); //_log.Error($"JobId:{jobInfo.Id}|JobName:{jobInfo.Name}启用失败!", e); } } else { new JobService().InsertLog(new JobLogEntity { JobId = jobInfo.Id, FireTime = DateTime.Now, FireDuration = 0, FireState = FireState.Error, Content = $"{jobInfo.Name}启用失败,请检查此Job执行类库是否上传到正确位置!", CreateTime = DateTime.Now }); } } else { new JobService().InsertLog(new JobLogEntity { JobId = jobInfo.Id, FireTime = DateTime.Now, FireDuration = 0, FireState = FireState.Error, Content = $"{jobInfo.Name}启用失败,Cron表达式错误!", CreateTime = DateTime.Now }); } }
public void TestSchedulerFactoryObjectWithPlainQuartzObjects() { IJobFactory jobFactory = new AdaptableJobFactory(); TestObject tb = new TestObject("tb", 99); JobDetailImpl jobDetail0 = new JobDetailImpl(); jobDetail0.JobType = typeof(IJob); jobDetail0.Name = "myJob0"; jobDetail0.Group = SchedulerConstants.DefaultGroup; jobDetail0.JobDataMap.Add("testObject", tb); Assert.AreEqual(tb, jobDetail0.JobDataMap.Get("testObject")); CronTriggerImpl trigger0 = new CronTriggerImpl(); trigger0.Name = "myTrigger0"; trigger0.Group = SchedulerConstants.DefaultGroup; trigger0.JobName = "myJob0"; trigger0.JobGroup = SchedulerConstants.DefaultGroup; trigger0.StartTimeUtc = DateTime.UtcNow; trigger0.CronExpressionString = "0/1 * * * * ?"; TestMethodInvokingTask task1 = new TestMethodInvokingTask(); MethodInvokingJobDetailFactoryObject mijdfb = new MethodInvokingJobDetailFactoryObject(); mijdfb.Name = "myJob1"; mijdfb.Group = SchedulerConstants.DefaultGroup; mijdfb.TargetObject = task1; mijdfb.TargetMethod = "doSomething"; mijdfb.AfterPropertiesSet(); IJobDetail jobDetail1 = (IJobDetail)mijdfb.GetObject(); SimpleTriggerImpl trigger1 = new SimpleTriggerImpl(); trigger1.Name = "myTrigger1"; trigger1.Group = SchedulerConstants.DefaultGroup; trigger1.JobName = "myJob1"; trigger1.JobGroup = SchedulerConstants.DefaultGroup; trigger1.StartTimeUtc = DateTime.UtcNow; trigger1.RepeatCount = SimpleTriggerImpl.RepeatIndefinitely; trigger1.RepeatInterval = TimeSpan.FromMilliseconds(20); IScheduler scheduler = A.Fake <IScheduler>(); A.CallTo(() => scheduler.GetTrigger(A <TriggerKey> ._)).Returns(null); A.CallTo(() => scheduler.GetJobDetail(A <JobKey> ._)).Returns(null); SchedulerFactoryObject schedulerFactoryObject = new TestSchedulerFactoryObject(scheduler); schedulerFactoryObject.JobFactory = jobFactory; schedulerFactoryObject.JobDetails = new IJobDetail[] { jobDetail0, jobDetail1 }; schedulerFactoryObject.Triggers = new ITrigger[] { trigger0, trigger1 }; try { schedulerFactoryObject.AfterPropertiesSet(); schedulerFactoryObject.Start(); } finally { schedulerFactoryObject.Dispose(); } A.CallTo(scheduler) .Where(x => x.Method.Name.Equals("set_JobFactory")) .WhenArgumentsMatch(x => x.Get <IJobFactory>(0) == jobFactory) .MustHaveHappened(); A.CallTo(() => scheduler.AddJob(jobDetail0, true, true)).MustHaveHappened(); A.CallTo(() => scheduler.AddJob(jobDetail1, true, true)).MustHaveHappened(); A.CallTo(() => scheduler.GetJobDetail(new JobKey("myJob0", SchedulerConstants.DefaultGroup))).MustHaveHappened(); A.CallTo(() => scheduler.GetJobDetail(new JobKey("myJob1", SchedulerConstants.DefaultGroup))).MustHaveHappened(); A.CallTo(() => scheduler.GetTrigger(new TriggerKey("myTrigger0", SchedulerConstants.DefaultGroup))).MustHaveHappened(); A.CallTo(() => scheduler.GetTrigger(new TriggerKey("myTrigger1", SchedulerConstants.DefaultGroup))).MustHaveHappened(); }
/// <summary> /// Called when the associated <see cref="IScheduler"/> is started, in order /// to let the plug-in know it can now make calls into the scheduler if it /// needs to. /// </summary> public virtual void Start() { try { if (jobFiles.Count > 0) { if (scanInterval > TimeSpan.Zero) { scheduler.Context.Put(JobInitializationPluginName + '_' + Name, this); } foreach (KeyValuePair <string, JobFile> pair in jobFiles) { JobFile jobFile = pair.Value; if (scanInterval > TimeSpan.Zero) { string jobTriggerName = BuildJobTriggerName(jobFile.FileBasename); TriggerKey tKey = new TriggerKey(jobTriggerName, JobInitializationPluginName); // remove pre-existing job/trigger, if any Scheduler.UnscheduleJob(tKey); // TODO: convert to use builder var trig = new SimpleTriggerImpl(); trig.Name = jobTriggerName; trig.Group = JobInitializationPluginName; trig.StartTimeUtc = SystemTime.UtcNow(); trig.EndTimeUtc = null; trig.RepeatCount = SimpleTriggerImpl.RepeatIndefinitely; trig.RepeatInterval = scanInterval; // TODO: convert to use builder JobDetailImpl job = new JobDetailImpl( jobTriggerName, JobInitializationPluginName, typeof(FileScanJob)); job.JobDataMap.Put(FileScanJob.FileName, jobFile.FilePath); job.JobDataMap.Put(FileScanJob.FileScanListenerName, JobInitializationPluginName + '_' + Name); scheduler.ScheduleJob(job, trig); Log.Debug("Scheduled file scan job for data file: {0}, at interval: {1}", jobFile.FileName, scanInterval); } ProcessFile(jobFile); } } } catch (SchedulerException se) { if (FailOnSchedulingError) { throw; } Log.Error("Error starting background-task for watching jobs file.", se); } finally { started = true; } }
/// <summary> /// 添加一个计划任务(映射程序集指定IJob实现类) /// </summary> /// <param name="tasksQz"></param> /// <returns></returns> public async Task <IResponseEntity> AddScheduleJobAsync(SysTaskQzEntity tasksQz) { if (tasksQz == null) { await Console.Out.WriteLineAsync("计划任务不存在!"); return(ResponseEntity.Error("计划任务不存在!")); } try { JobKey jobKey = new JobKey(tasksQz.Id.ToString(), tasksQz.JobGroup); if (await _scheduler.Result.CheckExists(jobKey)) { await Console.Out.WriteLineAsync($"该任务计划已经在执行:【{tasksQz.Name}】,请勿重复启动!"); return(ResponseEntity.Error($"该任务计划已经在执行:【{tasksQz.Name}】,请勿重复启动!")); } #region 设置开始时间和结束时间 if (tasksQz.BeginTime == null) { tasksQz.BeginTime = DateTime.Now; } DateTimeOffset starRunTime = DateBuilder.NextGivenSecondDate(tasksQz.BeginTime, 1);//设置开始时间 if (tasksQz.EndTime == null) { tasksQz.EndTime = DateTime.MaxValue.AddDays(-1); } DateTimeOffset endRunTime = DateBuilder.NextGivenSecondDate(tasksQz.EndTime, 1);//设置暂停时间 #endregion #region 通过反射获取程序集类型和类 Assembly assembly = Assembly.Load(new AssemblyName(tasksQz.AssemblyName)); Type jobType = assembly.GetType(tasksQz.AssemblyName + ".Jobs." + tasksQz.ClassName); #endregion //传入反射出来的执行程序集 IJobDetail job = new JobDetailImpl(tasksQz.Id.ToString(), tasksQz.JobGroup, jobType); job.JobDataMap.Add("JobParams", tasksQz.JobParams); if (tasksQz.ConnectionParam.IsNull()) { await Console.Out.WriteLineAsync($"任务依赖数据库为空!"); return(ResponseEntity.Error($"任务依赖数据库为空!")); } job.JobDataMap.Add("ConnectionParam", tasksQz.ConnectionParam); ITrigger trigger; #region 泛型传递 //IJobDetail job1 = JobBuilder.Create<T>() // .WithIdentity(sysSchedule.Name, sysSchedule.JobGroup) // .Build(); #endregion if (tasksQz.Cron != null && CronExpression.IsValidExpression(tasksQz.Cron) && tasksQz.TriggerType > 0) { trigger = CreateCronTrigger(tasksQz); } else { trigger = CreateSimpleTrigger(tasksQz); } //判断任务调度是否开启 if (!_scheduler.Result.IsStarted) { await StartScheduleAsync(); } // 告诉Quartz使用我们的触发器来安排作业 await _scheduler.Result.ScheduleJob(job, trigger); await Console.Out.WriteLineAsync($"启动任务:【{tasksQz.Name}】成功"); return(ResponseEntity.Ok($"启动任务:【{tasksQz.Name}】成功")); } catch (Exception ex) { throw; } }