Quartz 第三课 More About Jobs & JobDetails(官方文档翻译)

时间:2023-01-03 23:03:51

当学完第二课之后,你欣喜的发现,让jobs工作起来是还是相当简单的。虽然让jobs运行起来很简单,对于其执行的关键内容还是需要知道的。它们是IJob接口中的Execute和JobDetails。

当你定义一个实现IJob接口的类的时候,你需要在里面实现实际需要执行的代码。Quartz.NET需要知道关于这代码的各种信息,这样 Quartz.NET才能像你期望的那样工作。这些细节是在JobDetail类中进行了描述,在上一节以及进行了简单的描述。

JobDetail由JobBuilder进行实例化的。JobBuilder容许开发人员使用 fluent interface.进行自定义JobDetail细节。

让我们花点时间看Job的机制以及在Quartz.NET中的生命周期。在第一节中已经看到的例子让我们再看一遍:

 // define the job and tie it to our HelloJob class
IJobDetail job = JobBuilder.Create<HelloJob>()
.WithIdentity("myJob", "group1")
.Build(); // Trigger the job to run now, and then every 40 seconds
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("myTrigger", "group1")
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds()
.RepeatForever())
.Build(); sched.ScheduleJob(job, trigger);

现在定义一个HelloJob 如下所示:

 public class HelloJob : IJob
{
public void Execute(IJobExecutionContext context)
{
Console.WriteLine("HelloJob is executing.");
}
}

请注意,在这里给scheduler 一个IJobDetail 实例,它只需要一个job实例就能进行运行。当scheduler执行job的时候,scheduler 会在调用Execute方法之前实例化一个job实例。 能实例化job的前提是job类中需要有个无参的构造函数。还有一个需要注意的是,在job类中定义任何数据字段其实没有什么太大的意义,因为在job的运行期间不会保留这些数据字段。

看到这你或许会问,那我如何为一个job提供属性和配置信息呢?并且这么能跟踪保持job的执行状态呢?要回答这些问题,关键要弄懂JobDataMap,它是JobDetail中的一部分。

JobDataMap

JobDataMap中可用于容纳任何数量的您希望提供给job实例在执行时(可序列化)的对象。JobDataMap实现了IDictionary接口,并为其添加了一些用于存储和检索基本类型的数据的实用方法。

 

下面是JobDataMap 快速上手代码,在添加job到scheduler之前先为JobDataMap添加一些数据 :

 // define the job and tie it to our DumbJob class
IJobDetail job = JobBuilder.Create<DumbJob>()
.WithIdentity("myJob", "group1") // name "myJob", group "group1"
.UsingJobData("jobSays", "Hello World!")
.UsingJobData("myFloatValue", 3.141f)
.Build();

下面是从执行的job中获取JobDataMap 数据

 Getting Values from a JobDataMap
public class DumbJob : IJob
{
public void Execute(JobExecutionContext context)
{
JobKey key = context.JobDetail.Key; JobDataMap dataMap = context.JobDetail.JobDataMap; string jobSays = dataMap.GetString("jobSays");
float myFloatValue = dataMap.GetFloat("myFloatValue"); Console.Error.WriteLine("Instance " + key + " of DumbJob says: " + jobSays + ", and val is: " + myFloatValue);
}
}

如果你准备使用一个持久的JobStore (JobStore 将在JobStore 部分进行讨论)你应该关注将在JobDataMap放些什么。因为它会被序列化,所以更容易产生版本问题。在标准的版本中是安全的,除此之外,任何人都可以改变你的实体类。所以不得不关心兼容性会被破坏的情况。

所以你可以把AdoJobStore and JobDataMap 放进map中,仅包含着原始函数与字符串数据,因此消除了序列化的各种问题。

由于Quartz默认JobFactory会再job实例化的时候去实例那些带有set属性的,所以当你添加带有set访问的属性的时候会在JobDataMap中创建对应的key将其保存。这样就不要进行显示区指示在execute方法方法中进行映射。

Trigger也有其相关的JobDataMap。当你需要多个Trigger进行调度和重复scheduler 这是非常有用的。每个Trigger是独立的,并且需要你单独输入配置信息。

JobDataMap 将JobExecutionContext 作为job执行时候的上下文。它里面包含了JobDataMap 和Trigger并且覆盖前面相同的值。

下面是来自JobExecutionContext获取数据的作业执行过程中合并的JobDataMap的一个简单的例子:

 public class DumbJob : IJob
{
public void Execute(IJobExecutionContext context)
{
JobKey key = context.JobDetail.Key; JobDataMap dataMap = context.MergedJobDataMap; // Note the difference from the previous example string jobSays = dataMap.GetString("jobSays");
float myFloatValue = dataMap.GetFloat("myFloatValue");
IList<DateTimeOffset> state = (IList<DateTimeOffset>) dataMap["myStateData"];
state.Add(DateTimeOffset.UtcNow); Console.Error.WriteLine("Instance " + key + " of DumbJob says: " + jobSays + ", and val is: " + myFloatValue);
}
}

或者,如果你想依靠的JobFactory“注入数据映射值到你的类,它可能看起来像这个:

 public class DumbJob : IJob
{
public string JobSays { private get; set; }
public float FloatValue { private get; set; } public void Execute(IJobExecutionContext context)
{
JobKey key = context.JobDetail.Key; JobDataMap dataMap = context.MergedJobDataMap; // Note the difference from the previous example IList<DateTimeOffset> state = (IList<DateTimeOffset>) dataMap["myStateData"];
state.Add(DateTimeOffset.UtcNow); Console.Error.WriteLine("Instance " + key + " of DumbJob says: " + JobSays + ", and val is: " + FloatValue);
}
}

你会注意到类的整个代码较长,但在execute()方法的代码是干净。人们还可以争辩说,虽然代码越长,它实际上花了更少的编码,如果程序员的IDE用于自动生成的属性,而不必手工编写单独的调用从JobDataMap中检索值。这是你的选择。

Job “Instances”

很多用户花费时间是困惑究竟是什么构成了“Job实例”。我们会尽力讲清楚这里,下面有关的工作状态和并发性的部分。

 

您可以创建一个job类,并通过创建JobDetails的多个实例的调度中存储了很多实例定义” - 每一个都有自己的属性和JobDataMap - 并且他们都增加到scheduler中

例如,你可以创建一个实现所谓的“SalesReportJob”IJob接口的类。这个job可能会被编码到期望发送给它(通过JobDataMap中)来指定销售报告应根据销售人员的姓名参数。然后它们可以创建多个定义的jobJobDetails),如“SalesReportForJoe”“SalesReportForMike”具有joe”“Mike”在相应JobDataMaps作为输入到各自的job指定。

 

Trigger启动,将一个JobDetail(实例定义),它会被自动加载,和job类是指通过对调度配置的JobFactory实例化。默认的JobFactory只是调用使用Activator.CreateInstance 调用job类的默认构造函数,然后尝试在匹配的JobDataMap中的键名该类调用setter属性。您可能希望创建自己的实现的JobFactory来完成的事情,如让你的应用程序的IoC或者DI容器产生/初始化作业实例。

 

In “Quartz speak”, 我们指的是每个存储的JobDetail作为“job定义”或“的JobDetail实例”,我们指的是每一个执行job作为“job实例”或“job定义实例”。通常,如果我们只是用这个词的“job”,我们指的是一个名为定义或JobDetail等。当我们指的是类实现job接口,我们平时使用的术语“job type”。

Job State and Concurrency

现在有一些关于Job的状态数据(aka JobDataMap)和并发性附加说明。可以天剑组合特性到你的job类上,来影响Quartz’的行为。

 

DisallowConcurrentExecution添加到Job类,告诉Quartz不执行给定的job定义的多个实例(即是指给定的job类)并发的属性。注意这里面的所说,必须小心使用。在上一节的例子中,如果“SalesReportJob”有这个属性,比只有一个“SalesReportForJoe”的实例可以在给定时间执行的,但它可以与“SalesReportForMike”的一个实例,同时执行。约束是基于一个实例定义(JobDetail等),而不是在工作类的实例。但是,它(quartz的设计),决定对类本身携带的属性,因为它决定对类进行怎样进行编译。

 

PersistJobDataAfterExecution是可以被添加到Job类,告诉quartz更新JobDetailJobDataMap存储的副本属性在execute()方法成功完成后(未抛出异常),使得同样的job在下一次执行(JobDetail)接收,而不是原先存储的值的更新的值。像DisallowConcurrentExecution属性,这适用于作业定义实例,而不是一个作业类的实例,虽然当时决定让job类携带的属性,因为它往往使对类是如何编码的差异(如'有状态'将需要显式地理解的执行方法中的代码)。

 

如果使用PersistJobDataAfterExecution属性,你应该认真考虑也使用DisallowConcurrentExecution属性,以避免留下什么数据时,同样的job(JobDetail)的两个实例并发执行存储可能的混淆(竞争条件)

Other Attributes Of Jobs

下面是可用于通过JobDetail等对象的job实例来定义的其他属性的简单总结:

 

持久性 - 如果job是不可持久的,它会自动从调度中删除,一旦不再有与之相关的任何活动的触发器。换句话说,非持久job具有一个寿命由其触发的存在的限制。

可恢复性 - 如果作业要求恢复,它是在调度的硬关闭的时间执行(即它崩溃中运行的过程中,或在机器关闭),然后重新执行当调度程序重新开始。在这种情况下,JobExecutionContext.Recovering属性将返回真。

JobExecutionException

最后,我们需要告诉你的IJob.Execute..)方法的一些细节。你应该从执行方法抛出的唯一类型是JobExecutionException。正因为如此,你通常应该换execute方法的全部内容以'try-catch“块。你也应该花一些时间看的JobExecutionException的文档,你的工作可以用它来提供调度各种指令为你想怎么异常进行处理。

Quartz 第三课 More About Jobs & JobDetails(官方文档翻译)的更多相关文章

  1. &lbrack;译&rsqb;Quartz&period;Net 框架 教程(中文版)2&period;2&period;x 之第三课 更多关于Jobs和JobDetails

    第三课 更多关于Jobs和JobDetails 在这二课我们已经学习到,Jobs接口非常容易实现,只有一个execute方法.我们需要再学习一些知识去理解jobs的本质,Job接口的execute方法 ...

  2. CodeIgniter框架入门教程——第三课 URL及ajax

    本文转载自:http://www.softeng.cn/?p=74 这节课讲一下CI框架的路由规则,以及如何在CI框架下实现ajax功能. 首先,先介绍CI框架的路由规则,因为CI框架是在PHP的基础 ...

  3. SQL初级第三课&lpar;下&rpar;

    我们续用第三课(上)的表 辅助表 Student                   Course               Score                    Teacher Sno ...

  4. shellKali Linux Web 渗透测试— 初级教程(第三课)

    shellKali Linux Web 渗透测试— 初级教程(第三课) 文/玄魂 目录 shellKali Linux Web 渗透测试—初级教程(第三课) 课程目录 通过google hack寻找测 ...

  5. 【第三课】ANR和OOM——贪快和贪多的后果(下)

    Out of Mana,法力耗尽. 内存就像法力,耗尽了就什么都不能做了.有时候一个应用程序占用了太大的内存,超过了Android系统为你规定的限制,那么系统就会干掉你,以保证其他app有足够的内存. ...

  6. 【第三课】ANR和OOM——贪快和贪多的后果(上)

    恼人的ANR 早先年用Android的时候,就连很多知名的app也总是莫名其妙崩溃,好像手机快的时候会崩溃,手机卡的时候app会卡死.卡死的时候会弹出来一个框,询问是要结束app还是继续等待.这就是A ...

  7. NeHe OpenGL教程 第三课:颜色渲染

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  8. BeagleBone Black 板第三课:Debian7&period;5系统安装和远程控制BBB板

    BBB板第三课:Debian7.5系统安装和远程控制BBB板 由于BBB板系统是Debian 7.4.据说使用Debian系统能够实现非常多BBB板的无缝连接.能够更好的学习和控制BBB板,所以就决定 ...

  9. 【Linux探索之旅】第二部分第三课:文件和目录,组织不会亏待你

    内容简介 1.第二部分第三课:文件和目录,组织不会亏待你 2.第二部分第四课预告:文件操纵,鼓掌之中 文件和目录,组织不会亏待你 上一次课我们讲了命令行,这将成为伴随我们接下来整个Linux课程的一个 ...

随机推荐

  1. C&num;的XML序列化及反序列化

    webservice在工作中用到的很多,基本都是以XML格式问通讯内容,其中最关键的就是XML串的序列化及反序列化. XML的运用中有两种信息传递,一种为XML的请求信息,另一种为返回信息,要运用XM ...

  2. 解决ecshop登陆自动退出的莫名现象

    最近在做ecshop的二次开发,程序发布后测试出现一个莫名的问题.点击几次页面后出现session丢失,需要重复登陆:本地怎么测试也都无法重现问题.一开始以为是修改程序的问题,可是怎么找都找不着问题所 ...

  3. CSS Select 标签取选中文本值

    $("#userDep").find("option:selected").text()

  4. CodeForces 702B Powers of Two

    简单题. 开一个$map$记录一下每个数字出现了几次,那么读入的时候$f[a[i]]+1$. 计算$a[i]$做出的贡献的时候,先把$f[a[i]]-1$,然后再枚举$x$,答案加上$f[{2^x} ...

  5. 前端面试题(5) 列举5种IE haslayout的属性及其值

    haslayout 是Windows Internet Explorer渲染引擎的一个内部组成部分.在Internet Explorer中,一个元素要么自己对自身的内容进行计算大小和组织,要么依赖于父 ...

  6. react-create-app 构建react项目的流程以及需要注意的地方

    Hello 小伙伴们,如果觉得本文还不错,记得给个 star , 小伙伴们的 star 是我持续更新的动力!GitHub 地址 React 系列文章代码地址 一 目录 不折腾的前端,和咸鱼有什么区别 ...

  7. 解决git仓库从http转为ssh所要处理的问题

    https://www.cnblogs.com/lusecond/p/7607198.html 为了方便,一般我们克隆仓库的时候会选择http或者https协议 git clone https://g ...

  8. Java实现非法访问异常

    创建ExceptionTest类,在该类的main()方法中,使用反射获得String类的所有域,不要使用setAccessible方法修改这些域的可见性,然后通过反射获得私有域中与”hash”相匹配 ...

  9. svn数据的备份

    svnadmin dump -r 0:HEAD [项目名称]>[存储的文件名].dump

  10. 转:sublime2 官方网址

    1. sublime2 官方网址 http://www.sublimetext.com/2