Quartz.Net(2)——NetCore3.1整合Quartz.Net

在上篇文章中Quartz.Net(1) 已经介绍了Quartz.Net的基本运用,该篇文章中将主要介绍NetCore3.1如何整合Quartz.Net,在后台运行定时job,并运用到上篇文章讲到的介绍点。

1 导入Nuget包

    <PackageReference Include="Quartz" Version="3.8.1" /><PackageReference Include="Quartz.Extensions.DependencyInjection" Version="3.8.1" /><PackageReference Include="Quartz.Extensions.Hosting" Version="3.8.1" />

Quartz 定时框架
Quartz.Extensions.DependencyInjection 用于在任务中导入其他的服务,整合使用NetCore的依赖注入框架
Quartz.Extensions.Hosting 使得Job在后台运行
.NetCore3.1 整合的版本均是3.8.1

2 定义Job

在定义Job时,用到了一个自定义特性JobAttribute,标注在实现了 I J o b \textcolor{red}{IJob} IJob类上,标明该任务的分组,名称,描述 ,触发器触发时的Corn表达式。
在实际运行的任务中将依赖于其他服务 如数据库服务、配置服务等,这里可以通过构造函数注入的方式引入其他的服务

    /// <summary>/// 自定义特性,用来标注Job运行信息/// </summary>[AttributeUsage(AttributeTargets.Class)]public class JobAttribute: Attribute{/// <summary>/// Job运行的Corn表达式/// </summary>public string Corn { get; set; }/// <summary>/// Job组/// </summary>public string JobGroup { get; set; }/// <summary>/// Job名称/// </summary>public string JobName { get; set; }/// <summary>/// Job描述/// </summary>public string JobDesc { get; set; }public JobAttribute(string Corn) {this.Corn = Corn;}}
    /// <summary>/// 新进员工创建用户刷脸照片Job /// 每天6点、14点执行/// </summary>[Job("0 0 6,14 * * ? *", JobDesc = "新进员工创建用户刷脸照片Job", JobGroup = "group2", JobName = "AddJob")]public class CreatePhotoJob : IJob{private FaceContext faceContext;private FaceWebService faceWebService;private ILogger<DelLeftEmpPhotoJob> logger;private IConfiguration configuration;public CreatePhotoJob(FaceContext faceContext, FaceWebService faceWebService, ILogger<DelLeftEmpPhotoJob> logger, IConfiguration configuration){this.faceContext = faceContext;this.faceWebService = faceWebService;this.logger = logger;this.configuration = configuration;}public async Task Execute(IJobExecutionContext context){//忽略任务的具体执行逻辑await RunJob();}}
    /// <summary>/// 删除离职人员刷脸照片Job/// 凌晨2点钟执行/// </summary>[Job("0 0 2 * * ? *", JobDesc = "删除离职人员刷脸照片Job",JobGroup ="group1",JobName ="DelJob")]public class DelLeftEmpPhotoJob : IJob{private FaceContext faceContext;private FaceWebService faceWebService;private ILogger<DelLeftEmpPhotoJob> logger;public DelLeftEmpPhotoJob(FaceContext faceContext, FaceWebService faceWebService, ILogger<DelLeftEmpPhotoJob> logger){this.faceContext = faceContext;this.faceWebService = faceWebService;this.logger = logger;}public async Task Execute(IJobExecutionContext context){//忽略任务的具体执行逻辑await RunJob();}
}

3 定义JobListener

为了更好的监听任务的运行状态,比如说在任务运行结束时向开发人员推送邮件,这里用到了任务监听器。实现方式时实现一个IJobListener。具体的业务逻辑请忽略,这里只是给出一个思路。

/// <summary>/// 任务监听器,使用AOP的思想监听任务[IJob]运行前后的动作/// </summary>public class MyJobListener : IJobListener{public string Name => "JobListener";public async Task JobExecutionVetoed(IJobExecutionContext context, CancellationToken cancellationToken = default){//throw new NotImplementedException();}/*** 监听Job运行前*/public async Task JobToBeExecuted(IJobExecutionContext context, CancellationToken cancellationToken = default){// throw new NotImplementedException();}/*** 在这里执行任务结束后的操作* 根据JobDetail所在的分组与名称分别发送不同内容的邮件信息*/public async Task JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException, CancellationToken cancellationToken = default){try{HRWebService webService = new HRWebService();var jobkey = context.JobDetail.Key;MailBody body = null ;if (jobkey.Group.Equals("group2") && jobkey.Name.Equals("AddJob")){body = MailBody.AddJobMail();}else if (jobkey.Group.Equals("group1") && jobkey.Name.Equals("DelJob")){body = MailBody.DelJobMail();}await webService.SendMail(body);}catch (Exception e) { }}}

3 配置服务

为了运行定义的IJob 示例,需要注册服务,触发器,监听器等信息,通常是在startup中进行配置。为了避免在startup中进行关于Quartz复杂的配置,这里将Job配置,触发器的配置等配置服务抽离到一个单独的配置类中,运用到了反射的思想。

    /// <summary>/// Quartz.Net 定时Job配置类/// </summary>public static class QuartzConfiguration{public static IServiceCollection AddMyQuartz(this IServiceCollection services) {//读取所有实现IJob接口的类,类上标注了JobAttribute类,调度器使用corn触发器去触发JOB任务//FaceJob是我定义Job的模块,这里只做参考,实际读取IJob的反射Type可能各不相同AssemblyName assemblyName = new AssemblyName("FaceJob");Assembly anotherModuleAssembly = Assembly.Load(assemblyName);var types = anotherModuleAssembly.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IJob))).Where(t => t.GetCustomAttribute<JobAttribute>() != null).ToArray();services.AddQuartz(configure =>{//Quartz3.8.1版本 默认是使用NetCore的依赖注入框架的,因此可以不用显示的定义此信息,但是在3.3.2及之前版本,不显示定义此配置是无法在Job中引入其他服务的//configure.UseMicrosoftDependencyInjectionJobFactory();foreach (Type type in types){//读取IJob上定jobAttribute(标注Job运行的信息) JobAttribute jobAttribute = type.GetCustomAttribute<JobAttribute>();var jobKey = new JobKey(jobAttribute.JobName, jobAttribute.JobGroup);//配置Jobconfigure.AddJob(type, jobKey, config =>{config.WithDescription(jobAttribute.JobDesc);});//配置触发器,统一使用Corn触发器configure.AddTrigger(config =>{config.ForJob(jobKey).WithCronSchedule(jobAttribute.Corn);});}//配置job监听器[监听任意组下的Job]configure.AddJobListener<MyJobListener>(GroupMatcher<JobKey>.AnyGroup());});//后台Job,任务在后台运行services.AddQuartzHostedService(options =>{options.WaitForJobsToComplete = true;});return services;} }

在startup中引入Quartz配置

public void ConfigureServices(IServiceCollection services){//忽略其他服务配置#region Quartz服务配置services.AddMyQuartz();#endregion}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/11916.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PyTorch中的torch.cuda.amp.autocast

torch.cuda.amp.autocast的使用 torch.cuda.amp.autocast是PyTorch中一种自动混合精度计算的方法&#xff0c;它允许在深度学习模型的训练过程中自动执行混合精度计算&#xff0c;从而加快训练速度并减少显存占用。 在使用torch.cuda.amp.autocast时&#xff0c;一般会将模型…

Ubuntu系统如何使用宝塔面板搭建HYBBS论坛并发布公网远程访问

文章目录 前言1. HYBBS网站搭建1.1 HYBBS网站安装1.2 HYBBS网站测试1.3. cpolar的安装和注册 2. 本地网页发布2.1.Cpolar临时数据隧道2.2.Cpolar稳定隧道&#xff08;云端设置&#xff09;2.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 3.公网访问测试总结 前言 在国内…

【智能算法】河马优化算法(HO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2024年&#xff0c;MH Amiri受到自然界河马社会行为启发&#xff0c;提出了河马优化算法&#xff08;Hippopotamus Optimization Algorithm, HO&#xff09;。 2.算法原理 2.1算法思想 …

动态IP的应用场景

动态IP适用于网络设备规模较小、需要灵活连接网络、经济条件有限或者需要临时建立网络的场景。

【C++】AVL

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、AVL 树 1.1、AVL树的概念 1.2、AVL树节点的定义 1.3、AVL树的插入 1.4、AVL树的旋转 1.4.1、新节点插入较高左子树的左侧---左左&#xff1a;右单旋 1…

Spring整体流程源码分析

DisableEncodeUrlFilter 防止sessionId被泄露 包装器模式 WebAsyncManagerIntegrationFilter WebAsyncManagerIntegrationFilter通常与Spring MVC的异步请求处理机制一起使用&#xff0c;确保在使用Callable或DeferredResult等异步处理方式时&#xff0c;安全上下文能够正…

CSP备考---位运算

前言 本期我们将学习位运算&#xff0c;与本期类型的考点&#xff08;二进制转换&#xff09;反码、补码、原码。 1、位运算是什么 首先我们需要先了解位运算是什么。 我们知道&#xff0c;计算机中的数在内存中都是以二进制形式进行存储的 &#xff0c;而位运算就是直接对整…

332_C++_mmap 映射文件或设备到进程的地址空间,或者创建一个新的映射区域

mmap : 映射文件或设备到进程的地址空间,或者创建一个新的映射区域(通常是匿名的) mmap 是 Linux 和其他类 Unix 系统中的一个系统调用,用于映射文件或设备到进程的地址空间,或者创建一个新的映射区域(通常是匿名的)。mmap 提供了灵活的方式来管理内存,它经常用于实现…

打造本地GPT专业领域知识库AnythingLLM+Ollama

如果你觉得openai的gpt没有隐私&#xff0c;或者需要离线使用gpt&#xff0c;还是打造专业领域知识&#xff0c;可以借用AnythingLLMOllama轻松实现本地GPT. AnythingLLMOllama 实现本地GPT步聚&#xff1a; 1 下载 AnythingLLM软件 AnythingLLM官网地址&#xff1a; Anythi…

功能卓越,未来可期!实在Agent智能体公测圆满收官

“被需要的智能才是实实在在的智能。”一直以来&#xff0c;实在智能始终坚持从行业本质出发思考如何围绕客户需求打造更智能、更普惠的智能体数字员工&#xff0c;切实关注用户真实的使用体验与感受。 自2020年7月起&#xff0c;实在智能率先推出第一代实在RPA数字员工&#…

SpringBoot设置默认文件大小

1、问题发现 有个需求&#xff0c;上传文件的时候&#xff0c;发现提示了这个错误&#xff0c;看了一下意思是说&#xff0c;文件超过了1M。 看我们文件的大小&#xff1a; 发现确实是&#xff0c;文件超出了1M&#xff0c;查了一下资料&#xff0c;tomcat默认上传文件大小为1M…

Python环形数组

在编程中&#xff0c;环形数组&#xff08;Circular Array&#xff09;是一种特殊的数组结构&#xff0c;其中最后一个元素连接到第一个元素&#xff0c;形成一个环形。这种结构在某些算法问题中很有用&#xff0c;例如约瑟夫环问题&#xff08;Josephus Problem&#xff09;。…

简单粗暴的翻译英文pdf

背景&#xff1a;看书的时候经常遇到英文pdf&#xff0c;没有合适的翻译软件可以快速翻译全书。这里提供一个解决方案。 Step 1 打开英文pdfCTRLA全选文字CTRLC复制打开记事本CTRLV复制保存为data.txt Step 2 写一个C脚本 // ToolPdf2Html.cpp : 此文件包含 "main&quo…

大型语言模型自我进化综述

24年4月来自北大的论文“A Survey on Self-Evolution of Large Language Models”。 大语言模型&#xff08;LLM&#xff09;在各个领域和智体应用中取得了显着的进步。 然而&#xff0c;目前从人类或外部模型监督中学习的LLM成本高昂&#xff0c;并且随着任务复杂性和多样性的…

子模块介绍,开发规范说明和工具类封装

在上一章的内容中&#xff0c;我们完成了聚合工程的搭建以及工程依赖的导入 当然我们会延续上一章的传统提供一个传送门给各位&#xff0c;如未完成上一章内容&#xff0c;请点击左侧->传送门 概述子模块 上一章我们已经创建了整个聚合工程 该聚合工程有以下子模块 <…

如何将一个Web应用部署到 Kubernetes 集群

Kubernetes&#xff08;常简称为 k8s&#xff09;是一个是一个开源的容器编排平台&#xff0c;由 Google 设计并捐赠给 Cloud Native Computing Foundation&#xff08;CNCF&#xff09;的开源平台。它旨在提供一个标准化的容器部署流程&#xff0c;让部署、扩展和管理应用程序…

C# WinForm —— 18 NumericUpDown 介绍

1. 简介 数字显示框&#xff0c;通过向上、向下按钮来 增加/减小 显示的数值 2. 常用属性 属性解释(Name)控件ID&#xff0c;在代码里引用的时候会用到,一般以 numUD 开头Hexadecimal数值 up-down 控件的值是否应以十六进制显示Increment每单击一下按钮&#xff0c;增加或减…

springboot基本使用十(搭建jpa)

jpa底层是hibernate,(ORM)对象关系映射技术 jpa依赖: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> 配置文件: server:port: 8088Spring:datasou…

音源分离|Music Source Separation in the Waveform Domain

一、文章摘要 本文中&#xff0c;比较了两种时域结构。首先将最初为语音源分离而开发的卷积tasnet应用于音乐源分离任务。虽然ConvTasnet击败了许多现有的频域方法&#xff0c;但正如人类评估所显示的那样&#xff0c;它存在明显的artifacts。本文提出了一种新的时域模型Demucs…

鸿蒙内核源码分析 (协处理器篇) | CPU 的好帮手

本篇很重要&#xff0c;对CP15协处理所有16个寄存器一一介绍&#xff0c;可能是全网介绍CP15最全面的一篇&#xff0c;鸿蒙内核的汇编部分(尤其开机启动)中会使用&#xff0c;熟练掌握后看汇编代码将如虎添翼。 协处理器 协处理器 (co-processor) 顾名思义是协助主处理器完成…