Quartz.net是一个功能比Timer强大的定时调度类库(C#)。网上大多是Java的Quartz教程,所以这里稍微记录下C#的Quartz.net。
Quaartz.net: DLL包下载地址(我自己上传的):https://download.csdn.net/download/qq_42354598/10597312
说明:调度器:IScheduer 作业:IJobDetail 触发器:ITrigger(类)
一个IScheduer可以调度多个Job,一个job能由多个ITrigger触发,但一个ITrigger只能触发一个Job。触发器定义时是和Job绑定在一起的。(次数主要用CRON调度表达式,特别强大)
cron在线生成器:http://cron.qqe2.com/
Quartz.net 程序包下载地址:
1.可以用VS的NUGet程序包管理器下载:下载命令:Install-Package Quartz
2.百度貌似找不到(官网也不能下),我是去CSDN下载的,比较全
//注意:下载的类库一定是Quartz.net(C#版本的)。Java版本的Quartz在这用不了(方法名略有差异)
Using Quartz;
Using Quartz.impl;
class A
{
public A(){}
public void AnExample(){
//1.先创建一个调度器实例
IScheduer isched=new StdScheduerFacktory().getScheduer();
//2.利用IJobDetail创建IJob(作业)
IJobDetail job1 = JobBuilder.Create
//传递参数的方法可以用
//①.UsingJobdata("参数") 这里只能传递数字和字符串.创建Job时也可以不传参数
//②job1.JobDataMap["name1"]=任何对象 存储对象后,JobDataMap是以Object类型存储的,取
//出来时要类型转换一下。Job1Class是一个类,job1与其Execute()方法绑定,job1触发时自动执行
//job1Class下的Execute()方法与job1自动绑定。
IJobDetail job1=JobBuilder.create
3.14).Build();
//3.创建与job1绑定的触发器。触发器的触发规则我用的是CRON表达式
ITrigger trigger1=TriggerBuilder.create().withIdentify("name1","group").withCronTrigger("Cron表达式").forJob(job1.key).startNow().Build();
//4.在调度器isched注册job1和trigger1
isched.ScheduerJob(job1,trigger1);
//同理可以创建多个job和与job对应的触发器,在调度器注册之。
}
1
注意:withIdentity()有3中:
1.withIdentity(jobkey或trigkey) 2.withIdentity(“name1”,“group1”) 3.withIdentity("name1")
//其中对key来说
Jobkey jkey=new Jobkey("name123") //输出jkey.toString() :Default.name123
Jobkey jkey2=new Jobkey("name111","group1111")//同理:name111,group111
TriggerKey tkey = new TriggerKey("trigger2");输出tkey.toString(): Default.trigger2
TriggerKey tkey = new TriggerKey("trigger222",“group987”);//同理:trigger222,group987
class job1Class:IJob
{
public job1Class(){}
public virture void Execute(IJobExecuteContext context){
//获取传递进来的参数
JobDataMap dataMap=context.IJobDetail.JobDataMap;
//get(“xx”),getString("xx"),getFloat("xx")
//取出之前创建JOB时传过来的参数。任何参数存进JobDataMap都会转化为Object类型,取出时要强制类型转换一下
DataTable DT=(DataTable)dataMap.get("参数名");
//注意:jobKey job1key=context.IJobDetail.key和triggerKey可以获取身份标识
//接下来用取得的参数执行你想要的的作业了
}
}
//测试结论:工厂通过getScheduler()得到的都是同一个调度器(得到的调度器对象均指向一个默认的实例)
//查:怎么创建带名字的不同的调度器?
//job和trigger的身份标识有3个重载
//在调度器里的job之间或trigger之间不能重名
//
public void asdf()
{
string cron1 = "0/5 * * * * ? *"; //每隔5秒触发器触发一次job.
//调度器q
IScheduler q = new StdSchedulerFactory().GetScheduler();
IJobDetail job1 = JobBuilder.Create().WithIdentity("job1").Build();
ITrigger trigger1 = TriggerBuilder.Create().WithIdentity("trigger1").WithCronSchedule(cron1).ForJob(job1.Key).StartNow().Build();
q.ScheduleJob(job1, trigger1);
//调度器a
IScheduler a = new StdSchedulerFactory().GetScheduler();
IJobDetail job_1 = JobBuilder.Create().WithIdentity("job1").Build();
ITrigger trigger_2 = TriggerBuilder.Create().WithIdentity("trigger2").WithCronSchedule(cron1).ForJob(job_1.Key).StartNow().Build();
//这里发生异常:Quartzxxx...xxx 调度器里已经存在名为job1的作业和trigger1的调度器了
a.ScheduleJob(job_1, trigger_1);
}
//通过jobdataMap可以传递任何类型的参数到ceshi类下的Execute方法
//ceshi类(随便建的一个测试类)必须实现IJob接口和该接口的Execute方法)
public void qwer()
{
IScheduler q = new StdSchedulerFactory().GetScheduler();
string cron1 = "0/5 * * * * ? *";
string cron2 = "0/10 * * * * ? *";
string cron3 = "0/20 * * * * ? *";
IJobDetail job1 = JobBuilder.Create().WithIdentity("job1").Build();
job1.JobDataMap["job1"] = "job1111";
IJobDetail job2 = JobBuilder.Create().WithIdentity("job2").Build();
job2.JobDataMap["job2"] = "job2222";
IJobDetail job3 = JobBuilder.Create().WithIdentity("job3").Build();
job3.JobDataMap["job3"] = "job3333";
ITrigger trigger1 = TriggerBuilder.Create().WithIdentity("trigger1").WithCronSchedule(cron1).ForJob(job1.Key).StartNow().Build();
ITrigger trigger2 = TriggerBuilder.Create().WithIdentity("trigger2").WithCronSchedule(cron2).ForJob(job2.Key).StartNow().Build();
ITrigger trigger3 = TriggerBuilder.Create().WithIdentity("trigger3").WithCronSchedule(cron3).ForJob(job3.Key).StartNow().Build();
q.ScheduleJob(job1, trigger1);
q.ScheduleJob(job2, trigger2);
q.ScheduleJob(job3, trigger3);
if (q.IsShutdown)
{
MessageBox.Show("1");
}
if (!q.IsStarted)
MessageBox.Show("2");
q.Start(); //启动调度器
}
//终止任务并删除(移除任务时,必须先获得该job和trigger的身份key)
//这里的例子大都是一个触发器对应一个job
public void deleteJob()
{
IScheduler isched = new StdSchedulerFactory().GetScheduler();
JobKey jkey = new JobKey("job2");
TriggerKey tkey = new TriggerKey("trigger2");
isched.PauseTrigger(tkey); //停止触发器
isched.UnscheduleJob(tkey); //移除触发器
isched.DeleteJob(jkey); //删除作业
}
//获取传递进来的参数:get(“xx”),getString("xx"),getFloat("xx")
//取出之前创建JOB时传过来的参数。任何参数存进JobDataMap都会转化为Object类型,取出时要强制类型转换一下成原来的类型
class ceshi:IJob
{
public virture void Execute(IJobExecuteContext context){
// jobKey job1key=context.IJobDetail.key和triggerKey可以获取身份标识
JobDataMap dataMap=context.IJobDetail.JobDataMap;
string name1=(string)dataMap.get("job1");
string name2=(string)dataMap.get("job2");
string name3=(string)dataMap.get("job3");
// DataTable DT=(DataTable)dataMap.get("参数名");
// string str=(string)dataMap.get("参数名");
if(name1="job1111")
console.writeLine("job1执行");
if(name2="job2222")
console.writeLine("job2执行");
if(name3="job3333")
console.writeLine("job3执行");
}
结果是每隔5秒输出:job1执行。每隔10秒输出:job2执行。每隔20秒输出:job3执行
我用了3个job,去调用ceshi类。所以在Execute要区分一i下不同的job。可以获得jobkey去区分。
jobKey job1key=context.IJobDetail.key
if(job.toString()=="name1,group1")
if(job.toString()=="Default.name11")
如果每一个JOB都有对应的一个execute类,那就不用区分了
更多详细可以参考:
后记:触发器的触发情况:用cron,比较强大。其他的一般般
还在继续完善中