搭建基于Quartz组件的定时调度任务

先在package包项目下,添加Quartz定时器组件:

新建类库项目Wsk.Core.QuartzNet,并且引用包类库项目。然后新建一个中间调度类,叫QuartzMiddleJob:

中间Job源码:

 public class QuartzMiddleJob : IJob
{
private readonly IServiceProvider _serviceProvider;
public QuartzMiddleJob(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public async Task Execute(IJobExecutionContext context)
{
using (var scope = _serviceProvider.CreateScope())
{
var jobType = context.JobDetail.JobType;
var job = scope.ServiceProvider.GetRequiredService(jobType) as IJob;
await job.Execute(context);
}
}
}

新建一个Job工厂类,叫WeskyJobFactory,用来获取刚刚创建的中间调度类的服务:

新建一个通用执行计划类,叫WeskyJobSchedule,用于每次任务都通过该计划进行生成:

计划类和枚举源码:

 public class WeskyJobSchedule
{
public WeskyJobSchedule(Type jobType, string cronExpression)
{
this.JobType = jobType ?? throw new ArgumentNullException(nameof(jobType));
CronExpression = cronExpression ?? throw new ArgumentNullException(nameof(cronExpression));
}
/// <summary>
/// Job类型
/// </summary>
public Type JobType { get; private set; }
/// <summary>
/// Cron表达式
/// </summary>
public string CronExpression { get; private set; }
/// <summary>
/// Job状态
/// </summary>
public JobStatus JobStatu { get; set; } = JobStatus.Init;
} /// <summary>
/// 运行状态
/// </summary>
public enum JobStatus : byte
{
[Description("Initialization")]
Init = 0,
[Description("Running")]
Running = 1,
[Description("Scheduling")]
Scheduling = 2,
[Description("Stopped")]
Stopped = 3, }

现在添加一个任务,新建任务类 MyJobs,并且继承自IJob,然后在Excute方法里面,就是该任务执行调度时候会进去执行的了:

似乎上面哪儿感觉不太对,咱们把原来的Job工厂里面到代码稍微调整下如下:

NewJob源码:

 public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
return _serviceProvider.GetRequiredService(bundle.JobDetail.JobType) as IJob;
}

现在新增一个静态类QuartzJobService,用来当做调度任务的中间启动项,并且把有关的一些服务注册进来:

对应源码:

  public static class QuartzJobService
{
public static void AddQuartzJobService(this IServiceCollection services)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
} services.AddSingleton<IJobFactory, WeskyJobFactory>();
services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();
services.AddSingleton<QuartzMiddleJob>(); services.AddSingleton<MyJobs>();
services.AddSingleton(
new WeskyJobSchedule(typeof(MyJobs), "0/1 * * * * ? ")
); services.AddHostedService<WeskyJobHostService>();
} }

最后,还少了个启动项,用来程序启动的时候,进行启动定时调度任务。新建类 WeskyJobHostService ,并且新建创建调度任务方法 CreateJob和触发器方法CreateTrigger:

然后,在开始和结束方法内:

以上源码如下:

  public class WeskyJobHostService: IHostedService
{
private readonly ISchedulerFactory _schedulerFactory;
private readonly IJobFactory _jobFactory;
private readonly IEnumerable<WeskyJobSchedule> _jobSchedules; public WeskyJobHostService(ISchedulerFactory schedulerFactory, IJobFactory jobFactory, IEnumerable<WeskyJobSchedule> jobSchedules)
{
_schedulerFactory = schedulerFactory ?? throw new ArgumentNullException(nameof(schedulerFactory));
_jobFactory = jobFactory ?? throw new ArgumentNullException(nameof(jobFactory));
_jobSchedules = jobSchedules ?? throw new ArgumentNullException(nameof(jobSchedules));
}
public IScheduler Scheduler { get; set; } public async Task StartAsync(CancellationToken cancellationToken)
{
Scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
Scheduler.JobFactory = _jobFactory;
foreach (var jobSchedule in _jobSchedules)
{
var job = CreateJob(jobSchedule);
var trigger = CreateTrigger(jobSchedule);
await Scheduler.ScheduleJob(job, trigger, cancellationToken);
jobSchedule.JobStatu = JobStatus.Scheduling;
}
await Scheduler.Start(cancellationToken);
foreach (var jobSchedule in _jobSchedules)
{
jobSchedule.JobStatu = JobStatus.Running;
}
} public async Task StopAsync(CancellationToken cancellationToken)
{
await Scheduler?.Shutdown(cancellationToken);
foreach (var jobSchedule in _jobSchedules)
{
jobSchedule.JobStatu = JobStatus.Stopped;
}
} private static IJobDetail CreateJob(WeskyJobSchedule schedule)
{
var jobType = schedule.JobType;
return JobBuilder
.Create(jobType)
.WithIdentity(jobType.FullName)
.WithDescription(jobType.Name)
.Build();
} private static ITrigger CreateTrigger(WeskyJobSchedule schedule)
{
return TriggerBuilder
.Create()
.WithIdentity($"{schedule.JobType.FullName}.trigger")
.WithCronSchedule(schedule.CronExpression)
.WithDescription(schedule.CronExpression)
.Build();
}
}

切回QuartzJobService,在 AddQuartzJobService 方法的最下方,添加上面启动服务的注册:

最后,在启动项目里面,添加对Wsk.CoreQuartz项目的引用,然后在WskService服务类下,添加对AddQuartzJobService服务的注册:

启动项目,看看效果:

由此可见,我们设置的每秒一次触发效果达成。为了检验是不是可以避免同一个调度任务产生并发,在调度任务方法里面,设置一个延时,看看效果:

运行结果:

说明在当前任务还没有完成的情况下,不会重复进入。如果要允许重复进,只需要把类上面的DisallowConcurrentExecution 标签注释掉就可以。

现在还原回去,然后在Cron表达式改写成定时10秒,看看效果:

运行结果:

以上就是本篇使用QuartzNet的全部内容,仅用于入门参考。对于其他定时用法、以及各种比较飘的使用,各位大佬可以自行变种。如果有什么建议或意见,也欢迎留言~~

十七、.net core(.NET 6)搭建基于Quartz组件的定时调度任务的更多相关文章

  1. springmvc+quartz简单实现定时调度

    一.简介:Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用.Quartz可以用来创建简单或为运行十 ...

  2. 基于Azkaban的任务定时调度实践

    本文由云+社区发表 作者:maxluo 一.Azkaban介绍 Azkaban是LinkedIn开源的任务调度框架,类似于JavaEE中的JBPM和Activiti工作流框架. Azkaban功能和特 ...

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

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

  4. 定时调度系列之Quartz.Net详解

    一. 背景 我们在日常开发中,可能你会遇到这样的需求:"每个月的3号给用户发信息,提醒用户XXX "."每天的0点需要统计前一天的考勤记录"."每个月 ...

  5. 定时调度篇之Quartz.Net详解(被替换)

    一. 背景 我们在日常开发中,可能你会遇到这样的需求:"每个月的3号给用户发信息,提醒用户XXX "."每天的0点需要统计前一天的考勤记录"."每个月 ...

  6. 定时调度系列之Quartz.Net详解(转)

    出处:https://www.cnblogs.com/yaopengfei/p/9216229.html 一. 背景 我们在日常开发中,可能你会遇到这样的需求:"每个月的3号给用户发信息,提 ...

  7. 十六、.net core(.NET 6)搭建基于Redis的Hangfire定时器

    搭建基于Redis的Hangfire定时器 Hangfire的定时配置信息会自动生成在指定到数据库内,包括关系型数据库或非关系型数据库内.目前为止,它在Redis.Oracle上面,可以支持最短15秒 ...

  8. 如何在ASP.NET 5上搭建基于TypeScript的Angular2项目

    一.前言 就在上月,公司的一个同事建议当前的前端全面改用AngularJs进行开发,而我们采用的就是ASP.NET 5项目,原本我的计划是采用TypeScript直接进行Angular2开发.所以借用 ...

  9. 基于 Quartz 开发企业级任务调度应用

    原文地址:http://www.ibm.com/developerworks/cn/opensource/os-cn-quartz/index.html Quartz 基本概念及原理 Quartz S ...

随机推荐

  1. springmvcdemo

      项目点击属性  2.3  转换成2.5    已经变成一个网站项目了     报错消失 pom.xml <project xmlns="http://maven.apache.or ...

  2. springboot开发浅谈 2021/05/11

    学习了这么久,本人希望有时间能分享一下,这才写下这篇浅谈,谈谈软件,散散心情. 这是本人的博客园账号,欢迎关注,一起学习. 一开始学习springboot,看了好多网站,搜了好多课程.零零落落学了一些 ...

  3. 最近做app项目中遇到的问题 以及一些常见注意事项

    最近做app项目中遇到的问题 1.时间兼容问题 var date = "2019-12-18 18:03:45" //不兼容代码 var newDate = new Date(da ...

  4. 敏杰开题——软工团队项目选择与NABCD分析

    这是一篇软件工程课程博客 Q A 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 团队项目选择 我们在这个课程的目标是 团队协作实践敏捷开发 这个作业在哪个具 ...

  5. ALPHA任务拆解

    项目 内容 这个作业属于哪个课程 BUAA2020软件工程 这个作业的要求在哪里 作业要求 我们在这个课程的目标是 学会团队合作,共同开发一个完整的项目 这个作业在哪个具体方面帮助我们实现目标 团队任 ...

  6. 8.Linux的目录管理

    3 Linux目录管理 3.1 Linux 文件与目录管理 3.1.1 目录常用命令 ls: 列出目录 cd: 切换目录 pwd: 显示目前的目录 mkdir:创建一个新的目录 rmdir:删除一个空 ...

  7. 6.注册CRT 以及SecureCRT访问

    1.什么是 SecureCRT SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,简单地说是Windows下登录Unix或Linux服务器主 机的软件. 1)准备工作:安装好Se ...

  8. Win10 禁用摄像头的方法及注意事项

    Win10 禁用摄像头的方法及注意事项 windows教程 2020-03-04  223 最新的Windows10系统中应该如何禁用摄像头呢?下面MS酋长与大家分享一下.当然,如果你说用个便利贴把摄 ...

  9. 马哥Linux SysAdmin学习笔记(一)

    Linux入门 Linux系统管理: 磁盘管理,文件系统管理 RAID基础原理,LVM2 网络管理:TCP/IP协议,Linux网络属性配置 程序包管理:rpm,yum 进程管理:htop,glanc ...

  10. Python socket 编程实验

    实验内容 1.编写一个基于UDP协议的客户机与服务器程序,实现相互通讯. 2.编写一个基于TCP协议的客户机与服务器程序,实现相互通讯. 3.捕获以上两种通讯的数据包,使用Wireshark进行分析, ...