Quartz.NET——作业调度组件

之前有个旧同事说他在项目中碰到某些功能需要使用到作业调度,于是找到了这个组件,据说相当好用,叫我有时间的话去了解一下。哈,于是小了解了一下,基本的使用算是明白了,深层次的东西就不了解了,本文简单记录一下最基本的使用!

    关于Quartz.NET,请访问它的网站: http://quartznet.sourceforge.net
    下载Quartz.NET,请直接进这里: http://quartznet.sourceforge.net/download.html

    首先看下在什么情况下我们会需要使用Quartz.NET来进行作业调度。在业务系统中,我们需要在每天的某一个时间点(例如晚上12点)中做一些统计报表的生成(例如生成当前的一些报表之类~);或者在网站中定时更新静态页面;或者在CRM中会在某些特殊的日子给予提醒。总之这些在根据预定好的时间规则里要去做某些事情的需求,都是可以用这个来解决的,当然了,前提是你开发的东西用的是.NET- -!

配置

    使用Quartz.NET,我们需要在配置文件里面添加点东西,首先是configSections节点中,我们要添加已下内容:
xml代码
?
1
2
3
4
< section name = "quartz" type = "System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
< sectionGroup name = "common" >
  < section name = "logging" type = "Common.Logging.ConfigurationSectionHandler, Common.Logging" />
</ sectionGroup >
    从上面添加的节点可以知道,肯定还有一些节点要添加的,在configuration节点中添加如下:
xml代码
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
< common >
  < logging >
    < factoryAdapter type = "Common.Logging.Simple.ConsoleOutLoggerFactoryAdapter, Common.Logging" >
      < arg key = "showLogName" value = "true" />
      < arg key = "showDataTime" value = "true" />
      < arg key = "level" value = "DEBUG" />
      < arg key = "dateTimeFormat" value = "HH:mm:ss:fff" />
    </ factoryAdapter >
  </ logging >
</ common >
< quartz >
  < add key = "quartz.scheduler.instanceName" value = "ExampleDefaultQuartzScheduler" />
  < add key = "quartz.threadPool.type" value = "Quartz.Simpl.SimpleThreadPool, Quartz" />
  < add key = "quartz.threadPool.threadCount" value = "10" />
  < add key = "quartz.threadPool.threadPriority" value = "2" />
  < add key = "quartz.jobStore.misfireThreshold" value = "60000" />
  < add key = "quartz.jobStore.type" value = "Quartz.Simpl.RAMJobStore, Quartz" />
</ quartz >
    注:以上的配置我还没有去仔细研究,我是在网上找中文资料抄的 - -!


Quartz.NET中几个重要的东西

1、作业调度器接口 IScheduler:这个接口负责启动一个作业和关闭一个作业,在启动和关闭作业之前,它还需要接受两个东西,一个是触发器(Trigger),一个是工作任务(JobDetail),要得到一个这样的接口的实例,我们还需要一个作业调度器工厂(ISchedulerFactory)。

2、作业调度器工厂接口 ISchedulerFactory:从命名来看,很明显是个工厂,专门产出IScheduler接口。

3、工作任务 JobDetail:它定义了你要定时去做什么工作,初始化一个该类的对象,我们要指定工作名(name),工作的组名(group),还有就是一个实现了IJob接口的类的类型(Type),就是说JobD 定义的是 做什么。

4、触发器 Trigger:据说Quartz.NET的触发器有很多,但是一般我们使用的是两种(都是继承了Trigger类的子类),一个是CronTrigger、另外一个是SimpleTrigger,我们要指定触发器名(name),触发器的的职责是定义工作任务的触发规则,也就是说Trigger 定义的是 啥时候做。

5、工作接口 IJob:我们需要把定时要做的事情(业务逻辑,例如去写一下数据库,写一下文件之类的)包装在一个类里面,这个类有一个特点,就是继承IJob这个接口,实现该接口的唯一方法Execute(JobExecutionContext context),在这个方法中将尽情地用代码实现我们的业务,所以可以说这个接口 定义的是如何做。

    网上找的资料基本一上来就是代码,没有对几个重要的对象就行讲解,这点比较遗憾!通过上面我们基本可以猜想出写出来的代码会是怎么样:我们先定义个类去实现IJob接口,把要做的“工作”写好,然后从作业调度器工厂(ISchedulerFactory)中拿个作业调度器(IScheduler)出来,定义好工作任务(JobDetail)指定这个工作任务的工作就是我们定义的那个类,定义好触发器(Trigger,也许是用CronTrigger、也许是用SimpleTrigger),把工作任务和触发器交给作业调度器,这样一来,就 确定了在什么时候要去做什么,也知道要怎么做了,最后调用作业调度器的一个方法(Statr())来开始任务!

代码示例

    下面用代码来说明问题,我们用代码来完成这样一个需求:在web项目中有一个txt文件(文件名为JobNotePad.txt),每隔十秒钟就把当前时间记录在里面。这里我们使用CronTrigger这种触发器来完成任务。首先我们要实现IJob接口,定义一个类如下:
c#代码
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using Quartz;
namespace WebApplication.Common
{
    public class MyJob : IJob
    {
        public void Execute(JobExecutionContext context)
        {
            try
            {           
                var path = @"H:\代码\测试代码\Csharp测试\QuartzTest\WebApplication\WebApplication\JobNotePad.txt" ;
                var curText = System.IO.File.ReadAllText(path);
                System.IO.File.WriteAllText(path, curText + "\r\n" + DateTime.Now.ToString());
            }
            catch (Exception ex)
            {
                throw ;
            }
        }
    }
}
    代码很简单,往txt文件里面写入当前时间。注意这里文件的路径,我直接用了物理路径,因为 Quartz.NET的工作是在它自己启的独立进程里面跑的,所以没办法通过当前的上下文对象把虚拟路径转为物理路径,也就是说var path = System.Web.HttpContext.Current.Server.MapPath("~/JobNotePad.txt");这样的代码会报错!这个大家可以去体会一下~~~

    接着我们要在Global.asax文件里写点代码,在网站开启的时候就开始作业,于是在Application_Start中加入如下代码:
c#代码
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/// <summary>
/// 作业调度器接口
/// </summary>
IScheduler scheduler;
protected void Application_Start( object sender, EventArgs e)
{
    try
    {
        // 创建一个工作调度器工场
        ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
        // 获取一个任务调度器
        scheduler = schedulerFactory.GetScheduler();
        // 创建一个工作
        JobDetail job = new JobDetail( "jobname1" , "jobgroup1" , typeof (Common.MyJob));
        // 创建一个触发器
        CronTrigger trigger = new CronTrigger();
        trigger.Name = "trigger1" ;
        trigger.JobName = "jobname1" ;
        trigger.JobGroup = "jobgroup1" ;
        trigger.Group = "triggergroup1" ;
        trigger.CronExpression = new CronExpression( "0/10 * * * * ?" );
        scheduler.AddJob(job, true );
        DateTime ft = scheduler.ScheduleJob(trigger);
        scheduler.Start();
    }
    catch (Exception ex)
    {
        throw ex;
    }
}
    这里我们发现把IScheduler的实例定义在方法外面了,理由是我们要在Application_End中用到它,如下(关闭作业调度):
c#代码
?
1
2
3
4
protected void Application_End( object sender, EventArgs e)
{
    scheduler.Shutdown( true );
}
    代码中有个地方比较有趣,就是trigger.CronExpression = new CronExpression("0/10 * * * * ?");这句,表示的是每隔10秒执行一次,从0秒开始,也就是说每个10秒、20秒、30秒...会fire一次工作。关于这个时间,这里有篇文章讲得很好, http://www.cnblogs.com/gooddasenlin/archive/2011/04/06/2007084.html

    修改一下需求,现在是要一秒钟内执行一次,执行10次就结束,我们可以使用另外一个触发器(SimpleTrigger)来完成任务,修改Application_Start代码如下:
c#代码
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
protected void Application_Start( object sender, EventArgs e)
{
    try
    {
        ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
        scheduler = schedulerFactory.GetScheduler();
        JobDetail job = new JobDetail( "jobname1" , "jobgroup1" , typeof (Common.MyJob));
        // 创建一个触发器
        SimpleTrigger trigger = new SimpleTrigger();
        trigger.Name = "trigger1" ;
        trigger.JobName = "jobname1" ;
        trigger.JobGroup = "jobgroup1" ;
        trigger.Group = "triggergroup1" ;
        trigger.RepeatInterval = new TimeSpan(0, 0, 1);
        trigger.RepeatCount = 10;
        scheduler.AddJob(job, true );
        DateTime ft = scheduler.ScheduleJob(trigger);
        scheduler.Start();
    }
    catch (Exception ex)
    {
        throw ex;
    }
}
    可以看到,我们其实只改了触发器的类型和触发器触发时间的定义。使用这两种触发器基本可以满足我们的需求了!

    测试代码,我们只需要运行网站,然后查看根目录下的JobNotePad.txt文件就知道鸟!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Quartz.NET是一个开源的作业调度框架,它可以帮助我们实现定时任务作业调度。在Quartz.NET中,我们可以通过实现IJob接口来定义一个作业,并且可以通过JobDataMap来传递参数。这篇文章将介绍如何在Quartz.NET中使用IJobExecutionContext来传递参数。 在Quartz.NET中,每次执行一个作业,都会创建一个新的JobExecutionContext对象。这个对象包含了当前作业的执行环境信息,包括作业的JobDetail信息、Trigger信息、Scheduler信息等等。除此之外,JobExecutionContext还提供了一个JobDataMap对象,用于存储传递给作业的参数。 下面是一个简单的示例,演示了如何在作业中获取JobDataMap中的值: ```csharp public class MyJob : IJob { public void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; string param1 = dataMap.GetString("param1"); int param2 = dataMap.GetInt("param2"); // 使用传递的参数执行作业逻辑 // ... } } ``` 在这个示例中,我们定义了一个作业MyJob,并实现了IJob接口。在Execute方法中,我们通过JobExecutionContext对象获取了JobDataMap,并从中获取了传递给作业的参数。接下来,我们可以使用这些参数执行作业逻辑。 除了JobDataMap之外,JobExecutionContext还提供了许多其他有用的信息,例如当前作业的执行时间、上次执行时间、下次执行时间等等。我们可以根据这些信息来编写更加复杂的作业逻辑。 总之,使用IJobExecutionContext可以方便地在Quartz.NET中传递参数,并且获取作业的执行环境信息。如果你想了解更多关于Quartz.NET的内容,可以参考Quartz.NET官方文档。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值