Quartz开发手册net版本.doc_第1页
Quartz开发手册net版本.doc_第2页
Quartz开发手册net版本.doc_第3页
Quartz开发手册net版本.doc_第4页
Quartz开发手册net版本.doc_第5页
免费预览已结束,剩余53页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Q官方开发指南第一课:使用Q1第二课:Jobs And Triggers3第三课:更多关于Jobs和JobDetails11第四课:关于Triggers更多内容15第五课: SimpleTrigger19第六课 : CronTrigger20第七课 : TriggerListeners和JobListeners22第八课:SchedulerListeners26第九课: JobStore28第十课: 配置、资源使用以及SchedulerFactory30第十一课: 高级(企业级)属性32第十二课:Quartz 的其他特性32在ASP.NET中使用Q进行工作调度34详细讲解Quartz.NET37第一课:使用Q使用scheduler之前应首先实例化它。使用SchedulerFactory可以完成scheduler的实例化。用户可直接地实例化这个工厂类并且直接使用工厂的实例(例如下面的例子)。 一旦一个scheduler被实例化,它就可以被启动(start),并且处于驻留模式,直到被关闭(shutdown)。注意,一旦scheduler被关闭(shutdown),则它不能再重新启动,除非重新实例化它。除非scheduler 被启动或者不处于暂停状态,否则触发器不会被触发(任务也不能被执行)。 下面是一个代码片断,这个代码片断实例化并且启动了一个scheduler,接着将一个要执行的任务纳入了进程。usingCommon.Logging;namespaceQuartz.Examples.Example1/*/ThisisjustasimplejobthatsaysHellototheworld./BillKratzerpublicclassHelloJob:IJobprivatestaticILog_log=LogManager.GetLogger(typeof(HelloJob);/*/Emptyconstructorforjobinitilization/Quartzrequiresapublicemptyconstructorsothatthe/schedulercaninstantiatetheclasswheneveritneeds./publicHelloJob()/*/Calledbythewhena/firesthatisassociatedwith/the./publicvirtualvoidExecute(JobExecutionContextcontext)/SayHellototheWorldanddisplaythedate/time_log.Info(string.Format(HelloWorld!-0,System.DateTime.Now.ToString(r); ILoglog=LogManager.GetLogger(typeof(SimpleExample);log.Info(-Initializing-);/FirstwemustgetareferencetoaschedulerISchedulerFactorysf=newStdSchedulerFactory();ISchedulersched=sf.GetScheduler();log.Info(-InitializationComplete-);log.Info(-SchedulingJobs-);/computeratimethatisonthenextroundminuteDateTimerunTime=TriggerUtils.GetEvenMinuteDate(newNullableDateTime(DateTime.Now);/definethejobandtieittoourHelloJobclassJobDetailjob=newJobDetail(job1,group1,typeof(HelloJob);/TriggerthejobtorunonthenextroundminuteSimpleTriggertrigger=newSimpleTrigger(trigger1,group1,runTime);/Tellquartztoschedulethejobusingourtriggersched.ScheduleJob(job,trigger);log.Info(string.Format(0willrunat:1,job.FullName,runTime.ToString(r);/Startupthescheduler(nothingcanactuallyrununtilthe/schedulerhasbeenstarted)sched.Start();log.Info(-StartedScheduler-);/waitlongenoughsothattheschedulerasanopportunityto/runthejob!log.Info(-Waiting90seconds-);/wait90secondstoshowjobsThread.Sleep(90*1000);/shutdowntheschedulerlog.Info(-ShuttingDown-);sched.Shutdown(true);log.Info(-ShutdownComplete-);如您所见,使用quartz相当简单,在第二课中,我们将给出一个Job和Trigger的快速预览,这样就能够充分理解这个例子。 自由、创新、研究、探索 本文出自 “张善友” 博客,请务必保留此出处/363653/74131第二课:Jobs And Triggers正如前面所提到的那样,通过实现IJob接口来使你的.NET组件可以很简单地被scheduler执行。下面是IJob接口: namespaceQuartz/*/Theinterfacetobeimplementedbyclasseswhichrepresentajobtobe/performed./Instancesofthisinterfacemusthavea/videsamechanismforinstancememberdata/thatmayberequiredbysomeimplementationsofthisinterface./JamesHouse/MarkoLahma(.NET)publicinterfaceIJob/*/Calledbythewhena/firesthatisassociatedwiththe./Theimplementationmaywishtosetaresultobjectonthe/JobExecutionContextbeforethismethodexits.Theresultitself/ismeaninglesstoQuartz,butmaybeinformativeto/sor/sthatarewatchingthejobs/execution./Theexecutioncontext.voidExecute(JobExecutionContextcontext);ILoglog=LogManager.GetLogger(typeof(SimpleTriggerExample);log.Info(-Initializing-);/FirstwemustgetareferencetoaschedulerISchedulerFactorysf=newStdSchedulerFactory();ISchedulersched=sf.GetScheduler();log.Info(-InitializationComplete-);log.Info(-SchedulingJobs-);/jobscanbescheduledbeforesched.start()hasbeencalled/getaniceroundtimeafewsecondsinthefutureDateTimets=TriggerUtils.GetNextGivenSecondDate(null,15);/job1willonlyfireonceatdate/timetsJobDetailjob=newJobDetail(job1,group1,typeof(SimpleJob);SimpleTriggertrigger=newSimpleTrigger(trigger1,group1,ts);/scheduleittorun!DateTimeft=sched.ScheduleJob(job,trigger);log.Info(string.Format(0willrunat:1andrepeat:2times,every3seconds,job.FullName,ft.ToString(r),trigger.RepeatCount,(trigger.RepeatInterval/1000);/job2willonlyfireonceatdate/timetsjob=newJobDetail(job2,group1,typeof(SimpleJob);trigger=newSimpleTrigger(trigger2,group1,job2,group1,ts,null,0,0);ft=sched.ScheduleJob(job),trigger);log.Info(string.Format(0willrunat:1andrepeat:2times,every3seconds,job.FullName,ft.ToString(r),trigger.RepeatCount,(trigger.RepeatInterval/1000);/job3willrun11times(runonceandrepeat10moretimes)/job3willrepeatevery10seconds(10000ms)job=newJobDetail(job3,group1,typeof(SimpleJob);trigger=newSimpleTrigger(trigger3,group1,job3,group1,ts,null,10,10000L);ft=sched.ScheduleJob(job,trigger);log.Info(string.Format(0willrunat:1andrepeat:2times,every3seconds,job.FullName,ft.ToString(r),trigger.RepeatCount,(trigger.RepeatInterval/1000);/thesamejob(job3)willbescheduledbyaanothertrigger/thistimewillonlyrunevery70seocnds(70000ms)trigger=newSimpleTrigger(trigger3,group2,job3,group1,ts,null,2,70000L);ft=sched.ScheduleJob(trigger);log.Info(string.Format(0willalsorunat:1andrepeat:2times,every3seconds,job.FullName,ft.ToString(r),trigger.RepeatCount,(trigger.RepeatInterval/1000);/job4willrun6times(runonceandrepeat5moretimes)/job4willrepeatevery10seconds(10000ms)job=newJobDetail(job4,group1,typeof(SimpleJob);trigger=newSimpleTrigger(trigger4,group1,job4,group1,ts,null,5,10000L);ft=sched.ScheduleJob(job,trigger);log.Info(string.Format(0willrunat:1andrepeat:2times,every3seconds,job.FullName,ft.ToString(r),trigger.RepeatCount,(trigger.RepeatInterval/1000);/job5willrunonce,fiveminutespastts(300secondspastts)job=newJobDetail(job5,group1,typeof(SimpleJob);trigger=newSimpleTrigger(trigger5,group1,job5,group1,ts.AddMilliseconds(300*1000),null,0,0);ft=sched.ScheduleJob(job,trigger);log.Info(string.Format(0willrunat:1andrepeat:2times,every3seconds,job.FullName,ft.ToString(r),trigger.RepeatCount,(trigger.RepeatInterval/1000);/job6willrunindefinitely,every50secondsjob=newJobDetail(job6,group1,typeof(SimpleJob);trigger=newSimpleTrigger(trigger6,group1,job6,group1,ts,null,SimpleTrigger.REPEAT_INDEFINITELY,50000L);ft=sched.ScheduleJob(job,trigger);log.Info(string.Format(0willrunat:1andrepeat:2times,every3seconds,job.FullName,ft.ToString(r),trigger.RepeatCount,(trigger.RepeatInterval/1000);log.Info(-StartingScheduler-);/Allofthejobshavebeenaddedtothescheduler,butnoneofthejobs/willrununtiltheschedulerhasbeenstartedsched.Start();log.Info(-StartedScheduler-);/jobscanalsobescheduledafterstart()hasbeencalled/job7willrepeat20times,repeateveryfiveminutesjob=newJobDetail(job7,group1,typeof(SimpleJob);trigger=newSimpleTrigger(trigger7,group1,job7,group1,ts,null,20,300000);ft=sched.ScheduleJob(job,trigger);log.Info(string.Format(0willrunat:1andrepeat:2times,every3seconds,job.FullName,ft.ToString(r),trigger.RepeatCount,(trigger.RepeatInterval/1000);/jobscanbefireddirectly(ratherthanwaitingforatrigger)job=newJobDetail(job8,group1,typeof(SimpleJob);job.Durable=(true);sched.AddJob(job,true);log.Info(Manuallytriggeringjob8);sched.TriggerJob(job8,group1);log.Info(-Waiting30seconds-);try/wait30secondstoshowjobsThread.Sleep(30*1000);/executingcatch(ThreadInterruptedException)/jobscanbere-scheduled/job7willrunimmediatelyandrepeat10timesforeverysecondlog.Info(-Rescheduling-);trigger=newSimpleTrigger(trigger7,group1,job7,group1,DateTime.Now,null,10,1000L);NullableDateTimeft2=sched.RescheduleJob(trigger7,group1,trigger);if(ft2.HasValue)log.Info(job7rescheduledtorunat:+ft2.Value.ToString(r);elselog.Error(Reschedulefailed,datewasnull);log.Info(-Waitingfiveminutes-);try/waitfiveminutestoshowjobsThread.Sleep(2*1000);/executingcatch(ThreadInterruptedException)log.Info(-ShuttingDown-);sched.Shutdown(true);log.Info(-ShutdownComplete-);/displaysomestatsabouttheschedulethatjustranSchedulerMetaDatametaData=sched.GetMetaData();log.Info(string.Format(Executed0jobs.,metaData.NumJobsExecuted); 这样,你会猜想出,当Job触发器触发时(在某个时刻),Execute (.)就被scheduler所调用。JobExecutionContext对象被传递给这个方法,它为Job实例提供了它的“运行时”环境-一个指向执行这个IJob实例的Scheduler句柄,一个指向触发该次执行的触发器的句柄,IJob的JobDetail对象以及一些其他的条目。 JobDetail对象由Quartz客户端在Job被加入到scheduler时创建。它包含了Job的各种设置属性以及一个JobDataMap对象,这个对象被用来存储给定Job类实例的状态信息。 Trigger对象被用来触发jobs的执行。你希望将任务纳入到进度,要实例化一个Trigger并且“调整”它的属性以满足你想要的进度安排。Triggers也有一个JobDataMap与之关联,这非常有利于向触发器所触发的Job传递参数。Quartz打包了很多不同类型的Trigger,但最常用的Trigge类是SimpleTrigger和CronTrigger。 SimpleTrigger用来触发只需执行一次或者在给定时间触发并且重复N次且每次执行延迟一定时间的任务。CronTrigger按照日历触发,例如“每个周五”,每个月10日中午或者10:15分。 为什么要分为Jobs和Triggers?很多任务日程管理器没有将Jobs和Triggers进行区分。一些产品中只是将“job”简单地定义为一个带有一些小任务标识的执行时间。其他产品则更像Quartz中job和trigger的联合。而开发Quartz的时候,我们决定对日程和按照日程执行的工作进行分离。(从我们的观点来看)这有很多好处。 例如:jobs可以被创建并且存储在job scheduler中,而不依赖于trigger,而且,很多triggers可以关联一个job.另外的好处就是这种“松耦合”能使与日程中的Job相关的trigger过期后重新配置这些Job,这样以后就能够重新将这些Job纳入日程而不必重新定义它们。这样就可以更改或者替换trigger而不必重新定义与之相连的job标识符。 当向Quartz scheduler中注册Jobs 和Triggers时,它们要给出标识它们的名字。Jobs 和Triggers也可以被放入“组”中。“组”对于后续维护过程中,分类管理Jobs和Triggers非常有用。Jobs和Triggers的名字在组中必须唯一,换句话说,Jobs和Triggers真实名字是它的名字+组。如果使Job或者Trigger的组为null,这等价于将其放入缺省的Scheduler.DEFAULT_GROUP组中。 现在对什么是Jobs 和 Triggers有了一般性的认识,可以通过第三课:更多关于Jobs和JobDetails的内容及第四课:关于Triggers更多的内容来深入地学习它们。 自由、创新、研究、探索本文出自 “张善友” 博客,请务必保留此出处/363653/74130第三课:更多关于Jobs和JobDetails如你所见,Job相当容易实现。这里只是介绍有关Jobs本质, IJob接口的Execute(.)方法以及JobDetails中需要理解的内容。 在所实现的类成为真正的“Job”时,期望任务所具有的各种属性需要通知给Quartz。通过JobDetail类可以完成这个工作,这个类在前面的章节中曾简短提及过。现在,我们花一些时间来讨论Quartz中Jobs的本质和Job实例的生命周期。首先让我们回顾一下第一课中所看到的代码片断: /definethejobandtieittoourHelloJobclassJobDetailjob=newJobDetail(job1,group1,typeof(HelloJob);/TriggerthejobtorunonthenextroundminuteSimpleTriggertrigger=newSimpleTrigger(trigger1,group1,runTime);/Tellquartztoschedulethejobusingourtriggersched.ScheduleJob(job,trigger);现在考虑如下定义的SimpleJob类:publicclassSimpleJob:IJobprivatestaticILog_log=LogManager.GetLogger(typeof(SimpleJob);/*/Emptyconstructorforjobinitilization./publicSimpleJob()/*/Calledbythewhena/firesthatisassociatedwith/the./publicvirtualvoidExecute(JobExecutionContextcontext)/Thisjobsimplyprintsoutitsjobnameandthe/dateandtimethatitisrunningstringjobName=context.JobDetail.FullName;_log.Info(string.Format(SimpleJobsays:0executingat1,jobName,DateTime.Now.ToString(r);注意,我们给scheduler传入了一个JobDetail实例,而且这个JobDetail实例只是简单提供了类名来引用被执行的Job。每次scheduler执行这个任务时,它就创建这个类的新实例,然后调用该实例的Execute(.)方法。对这种行为的一个推论就是Job类必须有一个无参数的构造函数。另外一个推论就是它使得Job类中定义的成员数据失去意义,因为这些成员数据值在每次执行的时候被“清空”了。 你可能要问,如何才能为每个Job实例提供属性和配置呢?而且,在执行中如何跟踪Job的状态呢?这些问题的答案是相同的:关键就是JobDataMap,这是JobDetail对象的一部分。 JobDataMap JobDataMap被用来保存一系列的(序列化的)对象,这些对象在Job执行时可以得到。JobDataMap是IDictionary接口的一个实现,而且还增加了一些存储和读取主类型数据的便捷方法。 下面是将Job加入到scheduler前使用的一些向JobDataMap加入数据的方法。 /passinitializationparametersintothejobjob1.JobDataMap.Put(ColorJob.FAVORITE_COLOR,Green);job1.JobDataMap.Put(ColorJob.EXECUTION_COUNT,1);下面的代码展示了在Job执行过程中从JobDataMap 获取数据的代码:/*/Thisisjustasimplejobthatreceivesparametersand/maintainsstate/BillKratzerpublicclassColorJob:IStatefulJobprivatestaticILog_log=LogManager.GetLogger(typeof(ColorJob);/parameternamesspecifictothisjobpublicconststringFAVORITE_COLOR=favoritecolor;publicconststringEXECUTION_COUNT=count;/SinceQuartzwillre-instantiateaclasseverytimeit/getsexecuted,membersnon-staticmembervariablescan/notbeusedtomaintainstate!privateint_counter=1;/*/Calledbythewhena/firesthatisassociatedwith/the./publicvirtualvoidExecute(JobExecutionContextcontext)/Thisjobsimplyprintsoutitsjobnameandthe/dateandtimethatitisrunningstringjobName=context.JobDetail.FullName;/GrabandprintpassedparametersJobDataMapdata=context.JobDetail.JobDataMap;stringfavoriteColor=data.GetString(FAVORITE_COLOR);intcount=data.GetInt(EXECUTION_COUNT);_log.Info(string.Format(ColorJob:0executingat1nfavoritecoloris2nexecutioncount(fromjobmap)is3nexecutioncount(fromjobmembervariable)is4,jobName,DateTime.Now.ToString(r),favoriteColor,count,_counter);/incrementthecountandstoreitbackintothe/jobmapsothatjobstatecanbeproperlymaintainedcount+;data.Put(EXECUTION_COUNT,count);/Incrementthelocalmembervariable/Thisservesnorealpurposesincejobstatecannot/bemaintainedviamember

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论