基于 Quartz.NET 实现可中断的任务

Quartz.NET 是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等。 Quartz.NET 允许开发人员根据时间间隔(或天)来调度作业。它实现了作业和触发器的多对多关系,还能把多个作业与不同的触发器关联。整合了 Quartz.NET 的应用程序可以重用来自不同事件的作业,还可以为一个事件组合多个作业。 在 Quartz.NET 的默认实现中 Worker 并非后台线程( IsBackground= false ),所以当我们终止调度器(调用 Scheduler.Shutdown() 方法)时,假如有一个比较耗时的 Job 正在执行,那么进程将不会立即结束,而是等待这个 Job 执行完毕再结束。

为了可以立即退出进程,我们需要了解一个 Quartz.NET 中内置的接口 : IInterruptableJob 。该接口表示一个可中断的任务,实现该接口的 Job 被认为是可以被中断执行的,下面是官方对 IInterruptableJob 接口的定义和解释:

The interface to be implemented by Quartz.IJobs that provide a mechanism for having their execution interrupted. It is NOT a requirement for jobs to implement this interface - in fact, for most people, none of their jobs will. The means of actually interrupting the Job must be implemented within the Quartz.IJob itself (the Quartz.IInterruptableJob.Interrupt method of this interface is simply a means for the scheduler to inform the Quartz.IJob that a request has been made for it to be interrupted). The mechanism that your jobs use to interrupt themselves might vary between implementations. However the principle idea in any implementation should be to have the body of the job's Quartz.IJob.Execute(Quartz.IJobExecutionContext) periodically check some flag to see if an interruption has been requested, and if the flag is set, somehow abort the performance of the rest of the job's work. An example of interrupting a job can be found in the source for the class Example7's DumbInterruptableJob It is legal to use some combination of System.Threading.Monitor.Wait(System.Object) and System.Threading.Monitor.Pulse(System.Object) synchronization within System.Threading.Thread.Interrupt and Quartz.IJob.Execute(Quartz.IJobExecutionContext) in order to have the System.Threading.Thread.Interrupt method block until the Quartz.IJob.Execute(Quartz.IJobExecutionContext) signals that it has noticed the set flag. If the Job performs some form of blocking I/O or similar functions, you may want to consider having the Quartz.IJob.Execute(Quartz.IJobExecutionContext) method store a reference to the calling System.Threading.Thread as a member variable. Then the implementation of this interfaces System.Threading.Thread.Interrupt method can call System.Threading.Thread.Interrupt on that Thread. Before attempting this, make sure that you fully understand what System.Threading.Thread.Interrupt does and doesn't do. Also make sure that you clear the Job's member reference to the Thread when the Execute(..) method exits (preferably in a finally block).

该接口定义了 Interrupt 方法,当调用 Scheduler.Shutdown() 方法时,Quartz.IScheduler 将会调用该方法来中断正在运行的任务。这就意味着,我们需要自己实现中断方法来停止当前的 Job 。 通常我们可以通过在任务执行时拿到当前工作的线程,并在中断时调用线程 Abort 方法的方式来终止当前任务。

    public class CommonInterruptableJob : IInterruptableJob
{
private Thread _currentThread; public void Execute(IJobExecutionContext context)
{
_currentThread = Thread.CurrentThread;
try
{
//TODO:编写你的任务代码
}
finally
{
_currentThread = null;
}
} public void Interrupt()
{
if (_currentThread != null)
{
_currentThread.Abort();
_currentThread = null;
}
}
}

这种方法简单粗暴,在一些要求不太严格的情况下表现令人满意。更为优雅的方式是定义布尔型字段 _stop 默认为 false ,在 Interrupt 方法被调用时将其设置为 true 。在 Execute 时不断检测该字段的值,并在合适的时机退出处理。

    public class NiceInterruptableJob : IInterruptableJob
{
private bool _stop; public void Execute(IJobExecutionContext context)
{
//假设我的任务是循环 1000 次处理某数据
for (var i = 0; !_stop && i < 1000; i++)
{
//TODO:处理代码
}
} public void Interrupt()
{
_stop = true;
}
}

本片文章对 Quartz.NET 进行了一个简单的介绍,且展示了两种不同的实现任务终止的方式。方式一简单粗暴,编写简单,适合大多数要求不太严格的场合。方式二更加优雅,对退出时机的掌控更加精确,不容易出现危险,但编写更加复杂。

基于 Quartz.NET 实现可中断的任务的更多相关文章

  1. 基于Quartz.NET 实现可中断的任务(转)

    Quartz.NET 是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等. Quartz.NET 允许开发人员根据时间间隔(或天)来调度作业.它实现了作 ...

  2. 基于Quartz实现简单的定时发送邮件

    一.什么是Quartz Quartz 是一个轻量级任务调度框架,只需要做些简单的配置就可以使用:它可以支持持久化的任务存储,即使是任务中断或服务重启后,仍可以继续运行.Quartz既可以做为独立的应用 ...

  3. Quartz.NET总结(五)基于Quartz.net 的开源任务管理平台

    前面总结了很多,关于Quartz.net 的文章,介绍了如何使用Quartz.net.不清楚的朋友,可以看我之前的系列文章,http://www.cnblogs.com/zhangweizhong/c ...

  4. 基于Quartz.NET构建自己的动态作业调度器

    在日常的开发中,运行定时任务基本上已经是很普遍的需求了,可以通过windows服务+timer组件来实现,也可以使用第三方框架来集成,Quartz.NET就是一款从JAVA的Quartz移植过来的一个 ...

  5. 任务调度之持久化(基于Quartz.net)

    上一篇我们了解了任务调度及他的远端管理方式,传送门:任务调度及远端管理(基于Quartz.net) 这篇我们要完成任务调度的持久化功能,即新增修改删除之类的功能,这必须得要有的,不然都不知道后台都有什 ...

  6. 任务调度之集群(基于Quartz.net)

    上一篇我们完成了任务调度的持久化,传送门:任务调度之持久化(基于Quartz.net) 这篇我们来完成Quartz.net的一个比较优秀的功能,即集群:集群可以提高任务调度服务的容灾性, 当一个节点宕 ...

  7. JobEngine 基于quartz.net 跨平台作业框架

    github:https://github.com/zzhi/JobEngine 基于quartz.net 的跨平台作业框架 quartz.net(https://github.com/quartzn ...

  8. Java 基于quartz实现定时 之二(XML方式配置)

    <!-- 在spring核心配置文件中进行如下配置 --> <!-- Spring基于quartz定时任务 --> <bean id="triggerByBea ...

  9. RDIFramework.NET框架基于Quartz.Net实现任务调度详解及效果展示

    在上一篇Quartz.Net实现作业定时调度详解,我们通过实例代码详细讲解与演示了基于Quartz.NET开发的详细方法.本篇我们主要讲述基于RDIFramework.NET框架整合Quartz.NE ...

随机推荐

  1. Windows和Linux系统如何退出python命令行

    python命令行是新手学习python过程中必须要学的一个工具,下面我们来看一下怎么退出python命令行. 第一种方式: 使用python提供的exit()函数,linux平台和windows平台 ...

  2. hbase优化操作与建议

    一.服务端调优 1.参数配置 1).hbase.regionserver.handler.count:该设置决定了处理RPC的线程数量,默认值是10,通常可以调大,比如:150,当请求内容很大(上MB ...

  3. 补充的css知识点

    1.文字一行显示   超出的用...表示 .ellipsis{ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  4. Scrum立会报告+燃尽图(Beta阶段第七次)

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2388 项目地址:https://coding.net/u/wuyy694 ...

  5. 软件工程第九周psp

    1.PSP表格 2.进度条 3.饼状图 4.折线图

  6. Java变量声明,实例化,问题

    1.变量在输出前必须实例化,这是因为只有声明,没有分配内存空间 在这种情况下会报错 2.实例化后,尽管没有赋值,可能是默认了吧,但也不会输出null,什么也没有输出 上面的理解可能是错的,a赋值了,就 ...

  7. pandas中DataFrame的ix,loc,iloc索引方式的异同

    pandas中DataFrame的ix,loc,iloc索引方式的异同 1.loc: 按照标签索引,范围包括start和end 2.iloc: 在位置上进行索引,不包括end 3.ix: 先在inde ...

  8. Log4Net的使用研究(一)

    等待研究中………… 20160421 标题:C#使用Log4Net记录日志   文章地址: http://www.cnblogs.com/wangsaiming/archive/2013/01/11/ ...

  9. DB2定位锁等待

    在应用中,我们经常会碰到sql执行很慢,但是数据库cpu和内存使用率又不高的情况,类似的问题基本上由于锁,排序等原因造成,本文主要描述如何去定位锁等待问题,谁在锁等待?等待谁持有的锁?锁在那个表? 一 ...

  10. jQuery之数组处理函数

    摘要:$.each,$.grep,$.map,$.merge,$.inArray,$.unique,$.makeArray 1. $.each(array, [callback]) 遍历[常用] 解释 ...