【C#】Quartz.NET怎么动态调用方法,并且根据指定时间周期执行,动态配置类何方法以及Cron表达式,有请DeepSeek

article/2025/6/27 19:50:12

🌹欢迎来到《小5讲堂》🌹
🌹这是《C#》系列文章,每篇文章将以博主理解的角度展开讲解。🌹
🌹温馨提示:博主能力有限,理解水平有限,若有不对之处望指正!🌹

在这里插入图片描述

目录

  • 前言
  • 效果
  • Quartz.NET插件
    • 1. 创建调度服务类
    • 2. 实现动态方法作业
    • 3. 在类库中暴露启动接口
    • 4. 使用示例
      • 在类库中定义要调用的方法
      • 在主程序中调用类库
    • 5.目标任务类
    • 6. 高级配置选项
    • 注意事项
  • 推荐文章

前言

任务调度一直都有在用,但是自己确实没有从零开始搭建何尝试创建,
最近有伙伴咨询任务调度怎么使用,因此自己也尝试了一边搭建,好在现在有AI工具,简单问一句就能出来我想要的效果,一起来看看吧。

效果

设置每隔10秒执行一次
在这里插入图片描述

Quartz.NET插件

要在类库中启动Quartz.NET动态调度功能,你需要创建一个可被主程序调用的入口点。以下是完整的实现方案:

1. 创建调度服务类

在你的类库中创建一个调度服务类,封装所有调度逻辑:

using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Specialized;
using System.Threading.Tasks;public class DynamicSchedulerService
{private IScheduler _scheduler;public async Task StartAsync(){// 1. 创建调度器var factory = new StdSchedulerFactory(GetSchedulerProperties());_scheduler = await factory.GetScheduler();// 2. 启动调度器await _scheduler.Start();}public async Task StopAsync(){if (_scheduler != null){await _scheduler.Shutdown();}}public async Task ScheduleMethodAsync(string methodName,string className,string cronExpression,string jobName = null,string groupName = "default"){if (_scheduler == null){throw new InvalidOperationException("调度器未启动,请先调用StartAsync()");}jobName ??= $"job_{methodName}_{Guid.NewGuid().ToString("N")}";// 创建作业var job = JobBuilder.Create<DynamicMethodJob>().WithIdentity(jobName, groupName).UsingJobData("MethodName", methodName).UsingJobData("ClassName", className).Build();// 创建触发器var trigger = TriggerBuilder.Create().WithIdentity($"trigger_{jobName}", groupName).WithCronSchedule(cronExpression).Build();// 安排作业await _scheduler.ScheduleJob(job, trigger);}private NameValueCollection GetSchedulerProperties(){// 可以在这里配置线程池、作业存储等设置return new NameValueCollection{// 示例配置,根据需求调整["quartz.threadPool.threadCount"] = "10",["quartz.scheduler.instanceName"] = "DynamicScheduler"};}
}

2. 实现动态方法作业

在类库中创建动态方法作业类:

using Quartz;
using System;
using System.Reflection;
using System.Threading.Tasks;public class DynamicMethodJob : IJob
{public Task Execute(IJobExecutionContext context){try{var dataMap = context.JobDetail.JobDataMap;var typeName = dataMap.GetString("ClassName");var methodName = dataMap.GetString("MethodName");if (string.IsNullOrEmpty(typeName) || string.IsNullOrEmpty(methodName)){throw new ArgumentException("ClassName和MethodName不能为空");}var type = Type.GetType(typeName);if (type == null){throw new TypeLoadException($"无法加载类型: {typeName}");}var method = type.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);if (method == null){throw new MissingMethodException($"在类型{typeName}中找不到方法{methodName}");}object instance = null;if (!method.IsStatic){instance = Activator.CreateInstance(type);}// 调用方法method.Invoke(instance, null);return Task.CompletedTask;}catch (Exception ex){// 记录日志或处理异常Console.WriteLine($"作业执行失败: {ex}");throw new JobExecutionException(ex);}}
}

3. 在类库中暴露启动接口

创建一个公共接口供外部调用:

public interface IDynamicScheduler
{Task StartSchedulerAsync();Task StopSchedulerAsync();Task ScheduleMethodAsync(string methodName, string className, string cronExpression, string jobName = null, string groupName = "default");
}public class DynamicScheduler : IDynamicScheduler
{private readonly DynamicSchedulerService _schedulerService = new DynamicSchedulerService();public Task StartSchedulerAsync() => _schedulerService.StartAsync();public Task StopSchedulerAsync() => _schedulerService.StopAsync();public Task ScheduleMethodAsync(string methodName, string className, string cronExpression, string jobName = null, string groupName = "default"){return _schedulerService.ScheduleMethodAsync(methodName, className, cronExpression, jobName, groupName);}
}

4. 使用示例

在类库中定义要调用的方法

public class SampleTasks
{public static void SendDailyReport(){Console.WriteLine($"{DateTime.Now}: 正在发送每日报告...");// 实际发送报告的逻辑}public void ProcessData(){Console.WriteLine($"{DateTime.Now}: 正在处理数据...");// 实际处理数据的逻辑}
}

在主程序中调用类库

using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using TaskV2.Base;namespace TaskV2
{public class Program{static async Task Main(string[] args){// 创建调度器实例IDynamicScheduler scheduler = new DynamicScheduler();try{// 启动调度器await scheduler.StartSchedulerAsync();Console.WriteLine("调度器已启动");/*// 调度静态方法 - 每天上午9点执行await scheduler.ScheduleMethodAsync("SendDailyReport","YourNamespace.SampleTasks", // 完整类名(包括命名空间)"0 0 9 * * ?"); // 每天9点*//*// 调度实例方法 - 每30分钟执行一次await scheduler.ScheduleMethodAsync("ProcessData","YourNamespace.SampleTasks","0 0/30 * * * ?");*/// 查询表 - 执行List<JobModel> list = new List<JobModel>();list.Add(new JobModel(){methodName = "TestData",className = "TaskV2.Work.AccessTokenShop",cronExpression = "0/10 * * * * ?",});// 调度实例方法foreach (JobModel obj in list){await scheduler.ScheduleMethodAsync(obj.methodName,obj.className,obj.cronExpression);}Console.WriteLine("按任意键停止...");Console.ReadKey();}finally{// 停止调度器await scheduler.StopSchedulerAsync();Console.WriteLine("调度器已停止");}}}
}

5.目标任务类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace TaskV2.Work
{public class AccessTokenShop{public int Id = 1;public void TestData(){Console.WriteLine($"TestData{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");}}
}

6. 高级配置选项

如果你需要更复杂的配置,可以扩展DynamicSchedulerService

// 在DynamicSchedulerService类中添加
public async Task ScheduleMethodWithParametersAsync(string methodName,string className,string cronExpression,object[] parameters,string jobName = null,string groupName = "default")
{jobName ??= $"job_{methodName}_{Guid.NewGuid().ToString("N")}";var job = JobBuilder.Create<DynamicMethodJob>().WithIdentity(jobName, groupName).UsingJobData("MethodName", methodName).UsingJobData("ClassName", className).UsingJobData("Parameters", parameters) // 传递参数.Build();var trigger = TriggerBuilder.Create().WithIdentity($"trigger_{jobName}", groupName).WithCronSchedule(cronExpression).Build();await _scheduler.ScheduleJob(job, trigger);
}

然后在DynamicMethodJob中处理参数:

// 修改DynamicMethodJob的Execute方法
var parameters = context.JobDetail.JobDataMap.Get("Parameters") as object[];
method.Invoke(instance, parameters);

注意事项

  1. 类型解析:确保Type.GetType()能找到你的类,可能需要使用程序集限定名称
  2. 依赖注入:如果需要使用DI容器创建实例,可以修改作业工厂
  3. 异常处理:确保作业中的异常被适当处理
  4. 生命周期:长时间运行的应用需要注意调度器的生命周期管理
  5. 日志记录:建议添加日志记录以便调试

这样实现后,你的类库就提供了一个完整的、可动态调度方法的Quartz.NET解决方案,可以在任何.NET应用程序中使用。

推荐文章

【C#】Quartz.NET怎么动态调用方法,并且根据指定时间周期执行,动态配置类何方法以及Cron表达式,有请DeepSeek

【C#】.net core6.0无法访问到控制器方法,直接404。由于自己的不仔细,出现个低级错误,这让DeepSeek看出来了,是什么错误呢,来瞧瞧

【C#】Html转Pdf,Spire和iTextSharp结合,.net framework 4.8

【C#】事务(进程 ID 64)与另一个进程被死锁在锁资源上,并且已被选作死锁牺牲品。请重新运行该事务。不能在具有唯一索引“XXX_Index”的对象“dbo.Test”中插入重复键的行。

【C#】使用DeepSeek帮助评估数据库性能问题,C# 使用定时任务,每隔一分钟移除一次表,再重新创建表,和往新创建的表追加5万多条记录

【C#】合理使用DeepSeek相关AI应用为我们提供强有力的开发工具,在.net core 6.0框架下使用JsonNode动态解析json字符串,如何正确使用单问号和双问号做好空值处理

【C#】已经实体类和动态实体类的反射使用方法,两分钟回顾,码上就懂

【C#】使用vue3的axios发起get和post请求.net framework部署的API显示跨域

【C#】.net core 6.0 webapi 使用core版本的NPOI的Excel读取数据以及保存数据

【C#】pdf按页分割文件,以及分页合并,效果还不错,你值得拥有

【C#】未能加载文件或程序集“CefSharp.Core.Runtime.dll”或它的某一个依赖项。找不到指定的模块。

【C#】.net core 6.0 在program时间格式统一json格式化,并列举program默认写法和简化写法

【C#】.net core 6.0 ApiController,API控制器方法,API接口以实体类作为接收参数应该注意的点

【C#】 SortedDictionary,查找字典中是否存在给定的关键字

【C#】.net core 6.0 MVC返回JsonResult显示API接口返回值不可被JSON反序列化

【C#】.net core 6.0 使用第三方日志插件Log4net,配置文件详细说明

【C#】使用代码实现龙年春晚扑克牌魔术(守岁共此时),代码实现篇

【C#】使用代码实现龙年春晚扑克牌魔术(守岁共此时),流程描述篇


http://www.hkcw.cn/article/WhPTcBDniG.shtml

相关文章

58岁女子山里失联6天5夜奇迹生还 救援队地毯式搜寻成功救出

6月1日,温州市黑马救援队发现一名失联6天5夜的老人。当时老人尚有生命体征,已被送往医院进一步救治。这名58岁的老人于5月27日在温州市鹿城区仰义教堂附近的山中失联,家属和救援队多日寻找未果。6月1日上午,黑马救援队接到鹿城区公安分局指挥中心指令后,组织了40余人,携带…

20250602在Ubuntu20.04.6下修改压缩包的日期和时间

rootrootrootroot-X99-Turbo:~$ ll -rwxrwxrwx 1 rootroot rootroot 36247187308 5月 23 10:23 Android13.0地面站.tgz* rootrootrootroot-X99-Turbo:~$ touch 1Android13.0地面站.tgz rootrootrootroot-X99-Turbo:~$ ll -rwxrwxrwx 1 rootroot rootroot 36247187308 6月…

金价再冲上3300美元 贸易局势推动

5月美股表现亮眼,标普500指数上涨6.15%,纳斯达克指数上涨9.56%,道琼斯指数上涨3.94%。尽管市场波动加剧,标普500和纳斯达克仍创下自2023年11月以来最大月度涨幅。特朗普宣布从6月4日起将进口钢铁关税提高至50%。这一消息导致现货黄金周一跳空高开,重新站上3300美元关口。亚…

graphviz, dot,python批量生成,示例1-10

0&#xff09;运行python脚本 import osdir1 "dot1" allfiles os.listdir(dir1) for i in range(len(allfiles)):ff dir1"\\"allfiles[i]file_name, file_extension os.path.splitext(ff)if not ".txt" file_extension.lower():continuecm…

光伏功率预测 | BiLSTM多变量单步光伏功率预测(Matlab完整源码和数据)

光伏功率预测 | BiLSTM多变量单步光伏功率预测&#xff08;Matlab完整源码和数据&#xff09; 目录 光伏功率预测 | BiLSTM多变量单步光伏功率预测&#xff08;Matlab完整源码和数据&#xff09;效果一览基本介绍程序设计参考资料 效果一览 基本介绍 光伏功率预测 | BiLSTM多变…

云计算数据治理

知识星球&#xff1a;数据书局。打算通过知识星球将这些年积累的知识、经验分享出来&#xff0c;让各位在数据治理、数据分析的路上少走弯路&#xff0c;另外星球也方便动态更新最近的资料&#xff0c;提供各位一起讨论数据的小圈子 1.摘要 云计算可以推动创新和各行业应用的…

「Python教案」字符串格式化操作

课程目标 1&#xff0e;知识目标 能够正确使用%、str.format()以及f-string进行数据格式化。能够分析不同格式化方法的适用场景及优缺点等。能够利用格式化控制符&#xff0c;例如对齐、宽度、精度、进制转换等进行格式化控制。 2&#xff0e;能力目标 能够根据需求选择合适…

空调清洗教程

&#x1f32c;️空调大清洗 流程过于复杂&#xff0c;建议网上找人清洗。如果想自己动手建议两人&#xff0c;可以站高的椅子&#xff08;安全为主&#xff09;。 &#x1f9f0; 工具准备&#xff1a; 螺丝刀螺丝收纳盒手套&#xff08;铝片很锋利&#xff0c;小心被划伤&am…

Docker 与 Harbor 私有仓库:镜像管理与版本控制的完整实践

在容器化大行其道的今天,Docker 镜像作为构建和部署容器化应用的基石,其管理和分发变得尤为关键。虽然 Docker Hub 等公共镜像仓库提供了便利,但在企业级或团队开发环境中,出于安全、效率、合规性和版本控制等考量,搭建一个私有 Docker 镜像仓库已成为不可或缺的一环。 本…

【深入详解】数据在内存中的存储:整数在内存中的存储、大小端字节序和字节序判断、浮点数在内存中的存储

目录 一、整数在内存中的存储 二、大小端字节序和字节序判断 &#xff08;一&#xff09;大小端是什么 &#xff08;二&#xff09;为什么会有大小端 &#xff08;三&#xff09;练习 1、练习(1) 2、练习(2) 3、练习(3) 4、练习(4) 5、练习(5) 6、练习(6) 三、浮点数…

前端八股之Vue

有使用过vue吗&#xff1f;说说你对vue的理解 对比维度详情Web 发展历程石器时代&#xff1a;静态网页&#xff0c;无数据库&#xff0c;后 CGI 技术实现网页与数据库交互&#xff0c;如 1998 年的 Google 文明时代&#xff1a;2005 年左右 ASP、JSP 出现&#xff0c;取代 CGI…

VMware Workstation17安装Rocky Linux 9.4

1、打开VMware虚拟机17&#xff0c;点击首页[创建新的虚拟机] 2、默认典型安装 3、选取镜像&#xff0c;或者选择最后一项&#xff0c;优选&#xff1a;稍后安装操作系统 备选&#xff1a;&#xff08;优选方便你调整配置&#xff09; 4、选择内核版本 5、选择安装名称及位置…

【含文档+PPT+源码】基于Python校园跑腿管理系统设计与实现

项目介绍 本课程演示的是一款基于Python校园跑腿管理系统设计与实现&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Python学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系统 3.…

洋流的实时原位预测

1. 摘要 洋流预测对于自主水下航行器的路径规划和控制至关重要。基于区域物理的预测模型提供了有效的预测&#xff0c;但对于AUV导航所需的实时预测而言&#xff0c;计算成本太高。虽然车辆传感器可以测量电流的空间演变&#xff0c;但时间预测仍然是一个悬而未决的问题&#…

汽车软件 OTA 升级技术发展现状与趋势

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…

RocketMQ介绍与部署

RocketMQ介绍 MQ&#xff1a;MessageQueue&#xff0c;消息队列。 MQ的作⽤主要&#xff1a; 异步能提⾼系统的响应速度、吞吐量。解耦&#xff1a;服务之间进⾏解耦&#xff0c;才可以减少服务之间的影响。解耦后可以实现数据分发&#xff0c;⽣产者发送⼀个消息后&#xff…

BUUCTF[极客大挑战 2019]Secret File 1题解

[极客大挑战 2019]Secret File 1 分析&#xff1a;解题界面1&#xff1a;界面二&#xff1a;界面3&#xff1a; 总结: 分析&#xff1a; 事后来看&#xff0c;这道题主打一个走一步看一步。我们只能从题目的标题中猜到&#xff0c;这道题与文件有关。 解题 界面1&#xff1a…

Nuxt3部署

最近接了一个项目&#xff0c;需要用到 nuxt3 技术来满足甲方所要求的需求&#xff0c;在部署的时候遇到了很多问题&#xff0c;这里我一一给大家讲述部署流程&#xff0c;以及所遇到的坑 打包部署 部署分为俩种方式&#xff1a; 静态(spa)部署 和 ssr部署 静态部署 静态部…

审计- 3- 风险评估:内部控制

1了解被审计单位及其环境 注册会计师应当实施风险评估程序&#xff0c;以了解被审计单位以及环境&#xff0c;从以下几个方面了解&#xff1a; 1.行业状况、法律环境与监管环境以及其他外部因素2.被审计单位的性质 1 所有权结构&#xff1b; 2 治理结构&#xff1b; 3 组织结构…

是否允诺伊朗保留铀浓缩活动?美国再出“罗生门”

当地时间6月2日,据美国阿克西奥斯新闻网报道,有两名知情人士透露,美国5月31日向伊朗提出的核协议提议允许伊朗在一段待定的时间内进行有限的低浓度铀浓缩。这与美高层官员的公开声明相矛盾,此前,美国中东问题特使威特科夫和国务卿鲁比奥已公开表示,美国不会允许伊朗进行铀…