AspNet Core结合Quartz使用定时任务且通过注入缓存或者配置参数

时间:2021-09-17 11:02:52

一、经常在项目会用到定时任务同步数据或更新缓存等操作,在很久以前我们可能经常会用一个多线程或timer来做定时任务,这样能实现比较简单轻量级的任务;对于任务多且都调用频率不一样的任务,我们都会用到Quartz.Net这个组件;

Quartz.NET是一个强大、开源、轻量的作业调度框架,你能够用它来为执行一个作业而创建简单的或复杂的作业调度。它有很多特征,如:数据库支持,集群,插件,支持cron-like表达式等等

二、  接下来简单演示一下Quartz使用:

2.1  首先新建一个AspNet Core API 项目,通过nuget包管理器安装引用Quartz

AspNet Core结合Quartz使用定时任务且通过注入缓存或者配置参数

2.2  新建一个模拟任务类UserInfoSyncjob 必须继承IJob接口

namespace QuartzDemo.Quarzs
{
public class UserInfoSyncjob : IJob
{ public Task Execute(IJobExecutionContext context)
{
return Task.Run(() =>
{
//.....
Console.WriteLine($"{DateTime.Now.ToString()}:开始执行同步第三方数据");
//....同步操作 });
}
}
}

2.2  声明一个启动类QuartzStartup,来控制任务启动关闭等方法

添加启动方法

   public async Task<string> Start()
{
//1、声明一个调度工厂
_schedulerFactory = new StdSchedulerFactory();
//2、通过调度工厂获得调度器
_scheduler = await _schedulerFactory.GetScheduler();
//3、开启调度器
await _scheduler.Start();
//4、创建一个触发器
var trigger = TriggerBuilder.Create()
.WithSimpleSchedule(x => x.WithIntervalInSeconds().RepeatForever())//每两秒执行一次
.Build();
//5、创建任务
var jobDetail = JobBuilder.Create<UserInfoSyncjob>()
.WithIdentity("job", "group")
.Build();
//6、将触发器和任务器绑定到调度器中
await _scheduler.ScheduleJob(jobDetail, trigger);
return await Task.FromResult("将触发器和任务器绑定到调度器中完成");
}

2.3  在网站启动完成时调用QuartzStartup的Start方法开启任务

先注入 Quartz调度类

AspNet Core结合Quartz使用定时任务且通过注入缓存或者配置参数

添加网站启动开始方法

AspNet Core结合Quartz使用定时任务且通过注入缓存或者配置参数

2.4、运行效果,运行之前将控制台开启(方便查看任务是否在执行,实际环境可写日志)

AspNet Core结合Quartz使用定时任务且通过注入缓存或者配置参数

AspNet Core结合Quartz使用定时任务且通过注入缓存或者配置参数

该调度任务完成,上方定义的触发器是2秒一次,所以该任务每隔2秒执行;(也可以通过配置文件,控制执行平率,cron表达式可以很好控制)

三、第二结简单演示了Quartz的基本用法,本文重点不是主要讲解Quartz的用法,上方只是为了没使用过Quartz的同行有个简单映像,如果想详细学习,博客园有很多类似的文章,也可以和我探讨一下!

本文重点是每个任务类怎么通过注入获取其他类的使用及参数配置类等等;

假如有这样一个需求,UserInfoSyncjob同步任务里面需要配置数据库连接参数和日志记录、缓存记录等,在之前我们可能通过配置类、日志类、缓存类以工厂形式单例创建获取。

在AspNet Core自带IOC容器框架,很多配置类、日志类、缓存类等等,在全局很多地方都会使用,我们现在做法就是把这些类注入到IOC容器中,如果需要的只需要从构造方法中获取;

我们都知道如果一个从构造方法中获取IOC容器里面的类型实例,必须该类型也要主要到IOC容器中,这样我们就要想办法把UserInfoSyncjob通过容器来创建生产;

通过源码发现在Quartz有一个默认的生成job的工厂类Quartz.Simpl.SimpleJobFactory

using System;
using Quartz.Logging;
using Quartz.Spi;
using Quartz.Util;
namespace Quartz.Simpl
{
/// <summary>
/// The default JobFactory used by Quartz - simply calls
/// <see cref="ObjectUtils.InstantiateType{T}" /> on the job class.
/// </summary>
/// <seealso cref="IJobFactory" />
/// <seealso cref="PropertySettingJobFactory" />
/// <author>James House</author>
/// <author>Marko Lahma (.NET)</author>
public class SimpleJobFactory : IJobFactory
{
private static readonly ILog log = LogProvider.GetLogger(typeof (SimpleJobFactory)); /// <summary>
/// Called by the scheduler at the time of the trigger firing, in order to
/// produce a <see cref="IJob" /> instance on which to call Execute.
/// </summary>
/// <remarks>
/// It should be extremely rare for this method to throw an exception -
/// basically only the case where there is no way at all to instantiate
/// and prepare the Job for execution. When the exception is thrown, the
/// Scheduler will move all triggers associated with the Job into the
/// <see cref="TriggerState.Error" /> state, which will require human
/// intervention (e.g. an application restart after fixing whatever
/// configuration problem led to the issue with instantiating the Job).
/// </remarks>
/// <param name="bundle">The TriggerFiredBundle from which the <see cref="IJobDetail" />
/// and other info relating to the trigger firing can be obtained.</param>
/// <param name="scheduler"></param>
/// <returns>the newly instantiated Job</returns>
/// <throws> SchedulerException if there is a problem instantiating the Job. </throws>
public virtual IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
IJobDetail jobDetail = bundle.JobDetail;
Type jobType = jobDetail.JobType;
try
{
if (log.IsDebugEnabled())
{
log.Debug($"Producing instance of Job '{jobDetail.Key}', class={jobType.FullName}");
} return ObjectUtils.InstantiateType<IJob>(jobType);
}
catch (Exception e)
{
SchedulerException se = new SchedulerException($"Problem instantiating class '{jobDetail.JobType.FullName}'", e);
throw se;
}
} /// <summary>
/// Allows the job factory to destroy/cleanup the job if needed.
/// No-op when using SimpleJobFactory.
/// </summary>
public virtual void ReturnJob(IJob job)
{
var disposable = job as IDisposable;
disposable?.Dispose();
}
}
}

SimpleJobFactory 实现了IJobFactory接口,通过源码发现我们如果要替换该工厂来控制job的生成,只需要创建一个IOCJobFactory来替换默认job工厂就行

 

public class IOCJobFactory : IJobFactory
{
private readonly IServiceProvider _serviceProvider;
public IOCJobFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
return _serviceProvider.GetService(bundle.JobDetail.JobType) as IJob; } public void ReturnJob(IJob job)
{
var disposable = job as IDisposable;
disposable?.Dispose(); }
}

在调度任务类里面重新设置job工厂  _scheduler.JobFactory = _iocJobfactory;

AspNet Core结合Quartz使用定时任务且通过注入缓存或者配置参数

在IOC中注入 UserInfoSyncjob、StdSchedulerFactory、IOCJobFactory    

 services.AddTransient<UserInfoSyncjob>();      // 这里使用瞬时依赖注入
services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();//注册ISchedulerFactory的实例。
services.AddSingleton<QuartzStartup>();
services.AddSingleton<IJobFactory,IOCJobFactory>();

修改UserInfoSyncjob任务类,可以通过构造方法注入的方式从容器中拿到日志实现类、缓存类等等

 public class UserInfoSyncjob : IJob
{
private readonly ILogger<UserInfoSyncjob> _logger;
// private readonly ICache _cache;
public UserInfoSyncjob(ILogger<UserInfoSyncjob> logger)
{
//_cache = cache;
_logger = logger;// EnginContext.Current.Resolve<ILogger<UserInfoSyncjob>>();
}
public Task Execute(IJobExecutionContext context)
{
return Task.Run(() =>
{
//.....
// Console.WriteLine($"{DateTime.Now.ToString()}:开始执行同步第三方数据");
_logger.LogInformation ($"{DateTime.Now.ToString()}:开始执行同步第三方数据");
//....同步操作
// 我们都知道如果一个从构造方法中获取IOC容器里面的类型,必须该类型也要主要到IOC容器中; });
}
}

调整后运行截图

AspNet Core结合Quartz使用定时任务且通过注入缓存或者配置参数

具体详细步骤请看源码:https://github.com/lxshwyan/QuartzDemo.git

 

  

AspNet Core结合Quartz使用定时任务且通过注入缓存或者配置参数的更多相关文章

  1. &period;net core&plus;topshelf&plus;quartz创建windows定时任务服务

    .net core+topshelf+quartz创建windows定时任务服务 准备工作 创建.net core 控制台应用程序,这里不做过多介绍 添加TopShelf包:TopShelf: 添加Q ...

  2. Spring Boot整合Quartz实现定时任务表配置

    最近有个小项目要做,spring mvc下的task设置一直不太灵活,因此在Spring Boot上想做到灵活的管理定时任务.需求就是,当项目启动的时候,如果有定时任务则加载进来,生成schedule ...

  3. &period;net core 基于 IHostedService 实现定时任务

    .net core 基于 IHostedService 实现定时任务 Intro 从 .net core 2.0 开始,开始引入 IHostedService,可以通过 IHostedService ...

  4. &period;NET Core开源Quartz&period;Net作业调度框架实战演练

    一.需求背景 人生苦短,我用.NET Core!作为一枚后端.NET开发人员,项目实践常遇到定时Job任务的工作,在Windows平台最容易想到的的思路Windows Service服务应用程序,而在 ...

  5. &period;NET Core 基于Quartz的UI可视化操作组件 GZY&period;Quartz&period;MUI 简介

    前言 最近在用Quartz做定时任务.虽然很方便,但是Quartz自己貌似是没有UI界面的..感觉操作起来 就很难受.. 查了一下,貌似有个UI组件 不过看了一下文档..直接给我劝退了..太麻烦了 我 ...

  6. 【AspNet Core】Nuget代理网站

    因为访问Nuget太慢,在Dotnet Core RC2发布前,我就基于Asp.Net做了一个Nuget代理网站 这是网站地址:http://nuget.lzzy.net/ Nuget源:http:/ ...

  7. 使用Quartz创建定时任务

    项目开发中经常需要定时循环执行某些任务 比如定时发送报表,定时发送邮件,亦或者定时清理缓存,定时更新数据等等 有些时候可以简单地利用Windows Server的计划任务执行程序 Linux也有相应的 ...

  8. Quartz&period;net 定时任务之Cron表达式

    一.cron表达式简单介绍和下载 1.在上一篇博客"Quartz.net 定时任务之简单任务"中,我简单介绍了quartz的使用,而这篇博客我将介绍cron的具体使用(不足之处望大 ...

  9. Spring集成Quartz完成定时任务

    在JavaEE系统中,我们经常会用到定时任务,比如每天晚上凌晨之后跑批处理或者是每天某个时刻群发消息等等. 我们可以使用java.util.Timer结合java.util.TimerTask来去完成 ...

随机推荐

  1. C&num; 在 vs2010 上开发 ActiveX 控件 【千辛万苦啊~】

    由于B/S项目中需要使用到读卡器的功能,但是由于厂家只有提供一个 读卡的dll,那么怎样能在客户端使用读卡器呢,那么进过一番查找,最总决定使用ActiveX 控件来做.由于是第一次接触到 Active ...

  2. 【JSP】JSP向MySQL写入&vert;读出中文数据——乱码问题

    注意第14行

  3. Asp&lowbar;CRUD

    Asp_增删改查.逻辑流程 启动服务器. 地址为127.0.0.1 端口为随机分配 2607 然后在浏览器中输入http://localhost:2670/CRUD_main.ashx 浏览器像服务器 ...

  4. 【转】monkey工具简介

    原文地址:http://www.testwo.com/blog/6188   一.Monkey 简介 Android的SDK 里面,Monkey的tools是一个命令行工具,当连接Android设备时 ...

  5. &lbrack;补档&rsqb;&lbrack;COGS 426&rsqb;血帆海盗

    [COGS 426]血帆海盗 题目 传送门:http://cogs.pro/cogs/problem/problem.php?pid=426 随着资本的扩大,藏宝海湾贸易亲王在卡利姆多和东部王国大陆各 ...

  6. java equals &equals;&equals; contentEquals

    equals与== 经常用于比较,用法如下:字符串比较相同用equals,普通数值(基本数据类型)比较用==, contentEquals下面讲 理论准备: java的基本类型如int.float,d ...

  7. java根据模板导出pdf

    在网上看了一些Java生成pdf文件的,写的有点乱,有的不支持写入中文字体,有的不支持模板,有的只是随便把数据放里面生成文件,完全不考虑数据怎样放置的以及以后的维护性,想想还是自己总结一个完全版的导出 ...

  8. shell:正则表达式和文本处理器

    1.什么是正则 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则. 生活中处处都是正则: 比如我们描述:4条腿 你可能会想 ...

  9. Nginx 连接限制和访问控制Nginx 连接限制和访问控制

    Nginx 连接限制和访问控制   前言 Nginx自带的模块支持对并发请求数进行限制, 还有对请求来源进行限制.可以用来防止DDOS攻击.阅读本文须知道nginx的配置文件结构和语法. 连接限制 l ...

  10. C89&lowbar;一些函数

    C89 string.h 中的函数: 复制函数 memcpy memmove strcpy strncpy 串接函数 strcat strncat 比较函数 memcmp strcmp strcoll ...