Asp.Net Core 使用Quartz基于界面画接口管理做定时任务

Asp.Net Core 使用Quartz基于界面画接口管理做定时任务

今天抽出一点点时间来造一个小轮子,是关于定时任务这块的。

这篇文章主要从一下几点介绍:

  1. 创建数据库管理表
  2. 创建web项目
  3. 引入quarzt nuget 包
  4. 写具体配置操作,实现定时任务处理

第一步:创建一个空web项目,引入quarzt nuget 包

Asp.Net Core 使用Quartz基于界面画接口管理做定时任务

创建TB.AspNetCore.Quartz web项目和TB.AspNetCore.Data 类库,在web项目中引入Quartz nuget包

第二部:数据库创建一张管理表

Asp.Net Core 使用Quartz基于界面画接口管理做定时任务

-- ----------------------------
-- Table structure for ScheduleInfo
-- ----------------------------
DROP TABLE IF EXISTS `ScheduleInfo`;
CREATE TABLE `ScheduleInfo` (
  `Id` int(11) NOT NULL AUTO_INCREMENT COMMENT '编号',
  `JobGroup` varchar(100) NOT NULL DEFAULT '' COMMENT '任务组',
  `JobName` varchar(50) NOT NULL DEFAULT '' COMMENT '任务名',
  `RunStatus` int(11) NOT NULL DEFAULT '0' COMMENT '运行状态',
  `CromExpress` varchar(40) NOT NULL DEFAULT '' COMMENT 'Crom表达式',
  `StarRunTime` datetime DEFAULT NULL COMMENT '开始运行时间',
  `EndRunTime` datetime DEFAULT NULL COMMENT '结束运行时间',
  `NextRunTime` datetime DEFAULT NULL COMMENT '下次运行时间',
  `Token` varchar(40) NOT NULL DEFAULT '' COMMENT 'Token',
  `AppID` varchar(40) NOT NULL DEFAULT '' COMMENT 'AppID',
  `ServiceCode` varchar(40) DEFAULT NULL,
  `InterfaceCode` varchar(40) DEFAULT NULL,
  `TaskDescription` varchar(200) DEFAULT NULL,
  `DataStatus` int(11) DEFAULT NULL COMMENT '数据状态',
  `CreateAuthr` varchar(30) DEFAULT NULL COMMENT '创建人',
  `CreateTime` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

创建数据库的表结构如图所示,接下来我们在Data项目里添加mysql数据库驱动nuget包

Asp.Net Core 使用Quartz基于界面画接口管理做定时任务

Asp.Net Core 使用Quartz基于界面画接口管理做定时任务

 

打开PM,执行数据库反向工程命令,从数据库生成model实体

Scaffold-DbContext "Server=你的服务器地址;Database=你的数据库;User=数据库用户名;Password=你的数据库密码;" "Pomelo.EntityFrameworkCore.MySql" -OutputDir Entity

 **2.1.1 建议不要选用,防坑!

 

 Asp.Net Core 使用Quartz基于界面画接口管理做定时任务

将链接字符串换成你自己的,我们又新添加了一个service文件夹和一个Enum文件夹

Asp.Net Core 使用Quartz基于界面画接口管理做定时任务

其中,BaseService 里封装了针对数据操作的基本crud,quartz里封装了关于定时任务的配置,enum里枚举了任务状态,具体代码如下

public enum JobStatus
    {
        [Description("已启用")]
        已启用,
        [Description("运行中")]
        待运行,
        [Description("执行中")]
        执行中,
        [Description("执行完成")]
        执行完成,
        [Description("执行任务计划中")]
        执行任务计划中,
        [Description("已停止")]
        已停止,
    }

下面是baseservice里具体方法

public class BaseService { protected static object obj = new object(); public ggb_offlinebetaContext _context; protected ggb_offlinebetaContext DataContext { get { if (_context == null) { _context = new ggb_offlinebetaContext(); } return _context; } } public BaseService() { } #region 封装基crud /// <summary> /// 只能是唯一记录 多记录引发异常 /// </summary> /// <typeparam name="TSource"></typeparam> /// <param name="predicate"></param> /// <returns></returns> public TSource Single<TSource>(Expression<Func<TSource, bool>> predicate = null) where TSource : class { if (predicate == null) { return this.DataContext.Set<TSource>().SingleOrDefault(); } return this.DataContext.Set<TSource>().SingleOrDefault(predicate); } /// <summary> /// 查询一条记录 /// </summary> /// <typeparam name="TSource"></typeparam> /// <param name="predicate"></param> /// <returns></returns> public TSource First<TSource>(Expression<Func<TSource, bool>> predicate = null) where TSource : class { if (predicate == null) { return this.DataContext.Set<TSource>().FirstOrDefault(); } return this.DataContext.Set<TSource>().FirstOrDefault(predicate); } /// <summary> /// where条件查询 /// </summary> /// <typeparam name="TSource"></typeparam> /// <param name="predicate"></param> /// <returns></returns> public IQueryable<TSource> Where<TSource>(Expression<Func<TSource, bool>> predicate = null) where TSource : class { if (predicate == null) { return this.DataContext.Set<TSource>().AsQueryable(); } return this.DataContext.Set<TSource>().Where(predicate); } /// <summary> /// 记录数 /// </summary> /// <typeparam name="TSource"></typeparam> /// <param name="predicate"></param> /// <returns></returns> public int Count<TSource>(Expression<Func<TSource, bool>> predicate = null) where TSource : class { if (predicate == null) { return this.DataContext.Set<TSource>().Count(); } return this.DataContext.Set<TSource>().Count(predicate); } /// <summary> /// 根据条件判断记录是否存在 /// </summary> /// <typeparam name="TSource"></typeparam> /// <param name="predicate"></param> /// <returns></returns> /// Any确定序列是否包含任何元素 public bool Exists<TSource>(Expression<Func<TSource, bool>> predicate = null) where TSource : class { if (predicate == null) { return this.DataContext.Set<TSource>().Any(); } return this.DataContext.Set<TSource>().Any(predicate); } /// <summary> /// 查询全部 /// </summary> /// <typeparam name="TSource"></typeparam> /// <returns></returns> public IQueryable<TSource> Query<TSource>() where TSource : class { return this.DataContext.Set<TSource>(); } /// <summary> /// paging the query 分页查询 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="query"></param> /// <param name="pageIndex">page index</param> /// <param name="pageSize">page size </param> /// <param name="count">total row record count</param> /// <returns></returns> public IQueryable<T> Pages<T>(IQueryable<T> query, int pageIndex, int pageSize, out int count) where T : class { if (pageIndex < 1) { pageIndex = 1; } if (pageSize < 1) { pageSize = 10; } count = query.Count(); query = query.Skip((pageIndex - 1) * pageSize).Take(pageSize); return query; } /// <summary> /// 分页查询 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="pageIndex"></param> /// <param name="pageSize"></param> /// <param name="count"></param> /// <returns></returns> public IQueryable<T> Pages<T>(int pageIndex, int pageSize, out int count) where T : class { if (pageIndex < 1) { pageIndex = 1; } if (pageSize < 1) { pageSize = 10; } var query = this.DataContext.Set<T>().AsQueryable(); count = query.Count(); query = query.Skip((pageIndex - 1) * pageSize).Take(pageSize); return query; } #endregion /// <summary> /// 做一次提交 /// </summary> #region Save Changes public void Save() { //todo 需要验证是否需要释放 using (this.DataContext) { this.DataContext.SaveChanges(); } } /// <summary> /// 添加 /// </summary> /// <param name="entity"></param> /// <param name="save"></param> public void Add(object entity, bool save = false) { this.DataContext.Add(entity); if (save) { this.Save(); } } /// <summary> /// 更新实体 /// </summary> /// <param name="entity"></param> /// <param name="save"></param> public void Update(object entity, bool save = false) { this.DataContext.Update(entity); if (save) { this.Save(); } } /// <summary> /// 更新2 /// </summary> /// <param name="list"></param> /// <param name="save"></param> public void Update(IEnumerable<object> list, bool save = false) { this.DataContext.UpdateRange(list); if (save) { this.Save(); } } /// <summary> /// 删除1 /// </summary> /// <param name="entity"></param> /// <param name="save"></param> public void Delete(object entity, bool save = false) { this.DataContext.Remove(entity); if (save) { this.Save(); } } /// <summary> /// 删除2 /// </summary> /// <param name="list"></param> /// <param name="save"></param> public void Delete(IEnumerable<object> list, bool save = false) { this.DataContext.RemoveRange(list); if (save) { this.Save(); } } #endregion ///// <summary> ///// 释放资源 ///// </summary> //public void Dispose() //{ // _context.Dispose(); //} }

下面是任务调度中心代码

/// <summary> /// 任务调度中心 /// </summary> public class JobCenter { /// <summary> /// 任务计划 /// </summary> public static IScheduler scheduler = null; public static async Task<IScheduler> GetSchedulerAsync() { if (scheduler != null) { return scheduler; } else { ISchedulerFactory schedf = new StdSchedulerFactory(); IScheduler sched = await schedf.GetScheduler(); return sched; } } /// <summary> /// 添加任务计划//或者进程终止后的开启 /// </summary> /// <returns></returns> public async Task<bool> AddScheduleJobAsync(ScheduleInfo m) { try { if (m != null) { if (m.StarRunTime == null) { m.StarRunTime = DateTime.Now; } DateTimeOffset starRunTime = DateBuilder.NextGivenSecondDate(m.StarRunTime, 1); if (m.EndRunTime == null) { m.EndRunTime = DateTime.MaxValue.AddDays(-1); } DateTimeOffset endRunTime = DateBuilder.NextGivenSecondDate(m.EndRunTime, 1); scheduler = await GetSchedulerAsync(); IJobDetail job = JobBuilder.Create<HttpJob>() .WithIdentity(m.JobName, m.JobGroup) .Build(); ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create() .StartAt(starRunTime) .EndAt(endRunTime) .WithIdentity(m.JobName, m.JobGroup) .WithCronSchedule(m.CromExpress) .Build(); //将信息写入 new ScheduleManage().AddSchedule(m); await scheduler.ScheduleJob(job, trigger); await scheduler.Start(); await StopScheduleJobAsync(m.JobGroup, m.JobName); return true; } return false; } catch (Exception ex) { //MyLogger.WriteError(ex, null); return false; } } /// <summary> /// 暂停指定任务计划 /// </summary> /// <returns></returns> public async Task<string> StopScheduleJobAsync(string jobGroup, string jobName) { try { scheduler = await GetSchedulerAsync(); //使任务暂停 await scheduler.PauseJob(new JobKey(jobName, jobGroup)); //更新数据库 new ScheduleManage().UpdateScheduleStatus(new ScheduleInfo() { JobName = jobName, JobGroup = jobGroup, RunStatus = (int)JobStatus.已停止 }); var status = new StatusViewModel() { Status = 0, Msg = "暂停任务计划成功", }; return JsonConvert.SerializeObject(status); } catch (Exception ex) { //MyLogger.WriteError(ex, null); var status = new StatusViewModel() { Status = -1, Msg = "暂停任务计划失败", }; return JsonConvert.SerializeObject(status); } } /// <summary> /// 恢复指定的任务计划**恢复的是暂停后的任务计划,如果是程序奔溃后 或者是进程杀死后的恢复,此方法无效 /// </summary> /// <returns></returns> public async Task<string> RunScheduleJobAsync(string jobGroup, string jobName) { try { //获取model var sm = new ScheduleManage().GetScheduleModel(new ScheduleInfo() { JobName = jobName, JobGroup = jobGroup }); await AddScheduleJobAsync(sm); sm.RunStatus = (int)JobStatus.已启用; //更新model new ScheduleManage().UpdateScheduleStatus(sm); scheduler = await GetSchedulerAsync(); //resumejob 恢复 await scheduler.ResumeJob(new JobKey(jobName, jobGroup)); var status = new StatusViewModel() { Status = 0, Msg = "开启任务计划成功", }; return JsonConvert.SerializeObject(status); } catch (Exception ex) { var status = new StatusViewModel() { Status = -1, Msg = "开启任务计划失败", }; return JsonConvert.SerializeObject(status); } } }

其他几个文件的细节代码我就不再粘贴,详细代码会推到github上去,接下来写一个控制器看看效果!

第四部:项目运行截图

Asp.Net Core 使用Quartz基于界面画接口管理做定时任务

 

Asp.Net Core 使用Quartz基于界面画接口管理做定时任务

Asp.Net Core 使用Quartz基于界面画接口管理做定时任务

 

 

具体详细的东西,也没有说的十分清晰,具体的代码可以到github上去查看,

项目github地址:https://github.com/TopGuo/TB.AspNetCore.Quarzt

如果您认为这篇文章还不错或者有所收获,您可以点击右下角的【推荐】按钮精神支持,因为这种支持是我继续写作,分享的最大动力

欢迎大家关注我都我的微信 公众号,公众号涨粉丝人数,就是你们对我的喜爱程度!

 Asp.Net Core 使用Quartz基于界面画接口管理做定时任务

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/101555.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 数据库的唯一索引_数据库唯一索引是什么

    数据库的唯一索引_数据库唯一索引是什么唯一索引是不允许表中任何两行具有相同索引值的索引。  当现有的数据中存在重复的键值时,大多数数据库不允许把新创建的唯一索引与表一起保存。数据库还可能防止添加将在表中创建重复键值的新数据。主键索引数据库表经常有一列或列组合,其值唯一标识表中的每一行。该列称为表的主键。在数据库关系图中为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型。该索引要求主键中的每个值都唯一。当在查询中使用主键

  • pandas用法-全网最详细教程

    pandas用法-全网最详细教程一、生成数据表1、首先导入pandas库,一般都会用到numpy库,所以我们先导入备用:importnumpyasnpimportpandasaspd2、导入CSV或者xlsx文件:df=pd.DataFrame(pd.read_csv(‘name.csv’,header=1))df=pd.DataFrame(pd.read_excel(‘nam…

  • django权限管理例子_django admin 自定义页面

    django权限管理例子_django admin 自定义页面前言上一篇我们分析了认证的源码,一个请求认证通过以后,第二步就是查看权限了,drf默认是允许所有用户访问权限源码分析源码入口:APIView.py文件下的initial方法下的check_per

  • PyQuery笔记

    PyQuery笔记1、初始化1.1、字符串初始化frompyqueryimportPyQueryaspyhtml=”’&lt;div&gt;  &lt;ul&gt;    &lt;liclass="item-0"&gt;firstitem&lt;/li&gt;    &lt;liclass="item-1"&gt;&lt;ahref="htt

  • python中循环遍历for怎么用_python遍历字典的值

    python中循环遍历for怎么用_python遍历字典的值在Python中,如何使用“for”循环遍历字典?今天我们将会演示三种方法,并学会遍历嵌套字典。在实战前,我们需要先创建一个模拟数据的字典。dict_1={‘Name’:’Zara’,’Age’:7,’Class’:’First’,’Address’:’Beijing’}方法1:使用For循环+索引进行迭代在Python中遍历字典的最简单方法,是将其直接放入for循环中。Python会自动将dict_1视为字典,并允许你迭代其key键。然后,我们就可以使用索引

  • WebRTC之ICE服务器coturn安装及部署

    WebRTC之ICE服务器coturn安装及部署GitHub:https://github.com/coturn/coturn一、安装sudoapt-getinstallcoturn

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号