上一章介绍了log4net的简单配置,这一章介绍一下quartz的简单使用,下一章介绍一下我得权限使用,然后就结束

本章主要介绍:

  • quartz在asp.net core中的使用

这个项目虽小,但是及其容易扩展,后面的业务直接能丢进来,使其更加丰富

废话不说开始介绍

一.基础类配置

  在domain里定义IJobCenter接口

  

  代码如下:

  

public interface IJobCenter{/// <summary>/// 添加定时任务/// </summary>/// <param name="m"></param>/// <returns></returns>Task<Result> AddScheduleJobAsync(TaskScheduleModel m);/// <summary>/// 暂停定时任务/// </summary>/// <param name="jobGroup"></param>/// <param name="jobName"></param>/// <returns></returns>Task<Result> StopScheduleJobAsync(string jobGroup, string jobName);/// <summary>/// 恢复定时任务/// </summary>/// <param name="jobGroup"></param>/// <param name="jobName"></param>/// <returns></returns>Task<Result> RunScheduleJobAsync(TaskScheduleModel m);}

  infrastructure里实现IJobCenter

  

  记得引入quartz的nuget

  

  代码如下:

  

/// <summary>/// 任务调度中心/// </summary>public class JobCenter:IJobCenter{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<Result> AddScheduleJobAsync(TaskScheduleModel m){Result result = new Result();try{if (m != null){DateTimeOffset starRunTime = DateBuilder.NextGivenSecondDate(m.StarRunTime, 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.CronExpress).Build();await scheduler.ScheduleJob(job, trigger);await scheduler.Start();result.Data = m;return result;}return result.SetError("传入实体为空");}catch (Exception ex){Log4Net.Error($"[JobCenter_AddScheduleJobAsync]_{ex}");return result.SetError(ex.Message);}}/// <summary>/// 暂停指定任务计划/// </summary>/// <returns></returns>public async Task<Result> StopScheduleJobAsync(string jobGroup, string jobName){Result result = new Result();try{scheduler = await GetSchedulerAsync();//使任务暂停await scheduler.PauseJob(new JobKey(jobName, jobGroup));                var status = new StatusViewModel(){Status = 0,Msg = "暂停任务计划成功",};result.Data = status.GetJson();return result;}catch (Exception ex){Log4Net.Error($"[JobCenter_StopScheduleJobAsync]_{ex}");var status = new StatusViewModel(){Status = -1,Msg = "暂停任务计划失败",};result.Data = status.GetJson();return result;}}/// <summary>/// 恢复指定的任务计划**恢复的是暂停后的任务计划,如果是程序奔溃后 或者是进程杀死后的恢复,此方法无效/// </summary>/// <returns></returns>public async Task<Result> RunScheduleJobAsync(TaskScheduleModel sm){Result result = new Result();try{#region 开任务//scheduler = await GetSchedulerAsync();//DateTimeOffset starRunTime = DateBuilder.NextGivenSecondDate(sm.StarRunTime, 1);//DateTimeOffset endRunTime = DateBuilder.NextGivenSecondDate(sm.EndRunTime, 1);//IJobDetail job = JobBuilder.Create<HttpJob>()//  .WithIdentity(sm.JobName, sm.JobGroup)//  .Build();//ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()//                             .StartAt(starRunTime)//                             .EndAt(endRunTime)//                             .WithIdentity(sm.JobName, sm.JobGroup)//                             .WithCronSchedule(sm.CronExpress)//                             .Build();//await scheduler.ScheduleJob(job, trigger);//await scheduler.Start();#endregionscheduler = await GetSchedulerAsync();//resumejob 恢复await scheduler.ResumeJob(new JobKey(sm.JobName, sm.JobGroup));var status = new StatusViewModel(){Status = 0,Msg = "恢复任务计划成功",};result.Data = status.GetJson();return result;}catch (Exception ex){Log4Net.Error($"[JobCenter_RunScheduleJobAsync]_{ex}");var status = new StatusViewModel(){Status = -1,Msg = "恢复任务计划失败",};result.Data = status.GetJson();return result;}}}

  写一个JobServiceExtensions拓展,其中里面有一个AddJobSerivce,用于在startup里添加启动服务

  

  这个拓展的主要作用是:程序启动,自动查询我的任务调度管理表,查询里面的状态是开启中的任务,并将其添加到定时任务中

  表结构大致如下:

  

   这里我们主要注意任务组和任务名,这两个何在一起,能顶一个唯一的任务,后面我们会在httpjob里根据不同的的任务组和任务名

    区分他们要执行的不同的逻辑

  

  代码很简单:如下

  

public class HttpJob : IJob{/// <summary>/// 通过group和name判断是要执行哪个任务  具体(任务执行逻辑)业务逻辑写后面/// </summary>/// <param name="context"></param>/// <returns></returns>public async Task Execute(IJobExecutionContext context){await Task.Run(() =>{var name = context.JobDetail.Key.Name;var group = context.JobDetail.Key.Group;if (group=="xx1"&&name=="xx2"){//do something
                }if (group == "xx2" && name == "xx3"){//do something also
                }Log4Net.Info($"执行任务_Name:{name}_Grop:{group}");});}}

  在domain里新增ITaskService接口,如下

  

  代码如下:

  

public interface ITaskService{//获取任务列表
        Result GetTaskList();//添加任务Task<Result> AddTaskAsync(TaskScheduleModel model);//修改任务Task<Result> ModifyTaskAsync(TaskScheduleModel model);//删除任务Task<Result> DelTaskAsync(TaskScheduleModel model);//暂停任务
        Result PauseTask();//开启任务
        Result StartTask();}

  在application 里实现这个接口

  

  代码如下:  

public class TaskService : BaseService, ITaskService{private IJobCenter jobCenter = ServiceCollectionExtension.Get<IJobCenter>();private MvcIdentity identity = (ServiceCollectionExtension.HttpContext.User.Identity as MvcIdentity);public async Task<Result> AddTaskAsync(TaskScheduleModel model){Result result = new Result();if (model == null){return result.SetError("Model 不能为空!");}if (string.IsNullOrEmpty(model.JobName)){return result.SetError("JobName 不能为空!");}if (string.IsNullOrEmpty(model.JobGroup)){return result.SetError("JobGroup 不能为空!");}if (model.StarRunTime == null){model.StarRunTime = DateTime.Now;}if (model.EndRunTime == null){model.EndRunTime = DateTime.MaxValue.AddDays(-1);}var info = await jobCenter.AddScheduleJobAsync(model);if (info.Status != 200){return result.SetError(info.Message);}base.Add(new TaskSchedule{Id = Guid.NewGuid().ToString("N"),CreateAuthr = identity.Name,CronExpress = model.CronExpress,EndRunTime = model.EndRunTime,StarRunTime = model.StarRunTime,JobGroup = model.JobGroup,JobName = model.JobName,RunStatus = model.RunStatus}, true);return result;}public async Task<Result> DelTaskAsync(TaskScheduleModel model){Result result = new Result();if (model == null){return result.SetError("Model 不能为空!");}if (string.IsNullOrEmpty(model.JobName)){return result.SetError("JobName 不能为空!");}if (string.IsNullOrEmpty(model.JobGroup)){return result.SetError("JobGroup 不能为空!");}//searchvar taskInfo = base.Single<TaskSchedule>(t => t.Id.Equals(model.Id));var info = await jobCenter.StopScheduleJobAsync(model.JobGroup, model.JobName);if (!info.Status.Equals(200)){return result.SetError(info.Message);}//delbase.Delete(taskInfo, true);return result;}public Result GetTaskList(){Result result = new Result();var query = base.Where<TaskSchedule>(t => !t.RunStatus.Equals(TaskJobStatus.JobHasDel)).Select(t => new{t.Id,t.JobGroup,t.JobName,t.RunStatus,t.StarRunTime,t.UpdateTime,t.CronExpress,t.EndRunTime,t.CreateTime}).ToList();List<TaskScheduleModel> _list = new List<TaskScheduleModel>();query.ForEach(t =>{_list.Add(new TaskScheduleModel(){Id = t.Id,JobGroup = t.JobGroup,JobName = t.JobName,_RunStatus = ((TaskJobStatus)t.RunStatus).GetString(),StarRunTime = t.StarRunTime,UpdateTime = t.UpdateTime,CronExpress = t.CronExpress,EndRunTime = t.EndRunTime,CreateTime = t.CreateTime});});result.Data = _list;return result;}public async Task<Result> ModifyTaskAsync(TaskScheduleModel model){Result result = new Result();if (model == null){return result.SetError("Model 不能为空!");}if (string.IsNullOrEmpty(model.JobName)){return result.SetError("JobName 不能为空!");}if (string.IsNullOrEmpty(model.JobGroup)){return result.SetError("JobGroup 不能为空!");}if (model.StarRunTime == null){model.StarRunTime = DateTime.Now;}if (model.EndRunTime == null){model.EndRunTime = DateTime.MaxValue.AddDays(-1);}//modifyvar taskInfo = base.Single<TaskSchedule>(t => t.Id.Equals(model.Id));if (taskInfo == null){return result.SetError("无此任务!");}//cronif (!taskInfo.CronExpress.Equals(model.CronExpress)){taskInfo.CronExpress = model.CronExpress;var stopInfo = await jobCenter.StopScheduleJobAsync(model.JobGroup, model.JobName);if (!stopInfo.Status.Equals(200)){return result.SetError(stopInfo.Message);}var info = await jobCenter.AddScheduleJobAsync(model);if (!stopInfo.Status.Equals(200)){return result.SetError(info.Message);}}//状态if (!taskInfo.RunStatus.Equals(model.RunStatus)){taskInfo.RunStatus = model.RunStatus;if (model.RunStatus != (int)TaskJobStatus.PauseJob){var stopInfo = await jobCenter.StopScheduleJobAsync(model.JobGroup, model.JobName);if (!stopInfo.Status.Equals(200)){return result.SetError(stopInfo.Message);}var info = await jobCenter.AddScheduleJobAsync(model);if (!stopInfo.Status.Equals(200)){return result.SetError(info.Message);}}else{var stopInfo = await jobCenter.StopScheduleJobAsync(model.JobGroup, model.JobName);if (!stopInfo.Status.Equals(200)){return result.SetError(stopInfo.Message);}}}//
            taskInfo.CreateAuthr = identity.Name;taskInfo.UpdateTime = DateTime.Now;taskInfo.EndRunTime = model.EndRunTime;taskInfo.StarRunTime = model.StarRunTime;taskInfo.JobGroup = model.JobGroup;taskInfo.JobName = model.JobName;base.Update(taskInfo, true);return result;}public Result PauseTask(){throw new NotImplementedException();}public Result StartTask(){throw new NotImplementedException();}}

View Code

  接着我们构建web页面

  在website里创建taskinfo控制器

  

  代码很简单只是做了一个跳转

  

  创建视图

  

  代码如下:  

@{ViewData["title"] = "定时任务管理";
}
<div class="row search"><div class="form-inline"><input type="text" class="form-control" placeholder="任务名称" ng-model="search.username" /></div><button class="btn btn-primary" type="button" ng-click="pagechanged(true)">搜索</button><button class="btn btn-primary" type="button" ng-click="addTask()">添加任务</button><button class="btn btn-primary" type="button" csv-header="getHeader()" ng-csv="_getCsv()" filename="taskList.csv" add-bom="true">导出</button>
</div>
@*弹出框*@
<div class="modal fade in" id="addmodel" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="mymodallabel"><div class="modal-dialog modal-lg" role="document" style="height:100%"><div class="modal-content"><div class="modal-header"><button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">close</span></button><h4>计划任务管理</h4></div><div class="modal-body" ng-form="mymodel"><div class="row"><div class="form-group col-sm-6"><label class="control-label col-sm-4">任务组:</label><div class="col-sm-8"><input type="text" class="form-control" ng-model="task.jobGroup" required placeholder="任务组" /></div></div><div class="form-group col-sm-6"><label class="control-label col-sm-4">任务名称:</label><div class="col-sm-8"><input type="text" class="form-control" ng-model="task.jobName" required placeholder="任务名称" /></div></div><div class="form-group col-sm-6"><label class="control-label col-sm-4">CronExpress:</label><div class="col-sm-8"><input type="text" class="form-control" ng-model="task.cronExpress" required placeholder="CronExpress" /></div></div><div class="form-group col-sm-6"><label class="control-label col-sm-4">运行状态:</label><div class="col-sm-8"><select class="form-control" required ng-model="task.runStatus">@*<option value="1">全部</option>*@<option value="1" selected>执行任务中</option><option value="2">暂停任务中</option><option value="4">任务关闭</option></select></div></div><div class="form-group col-sm-6"><label class="control-label col-sm-4">开始时间:</label><div class="col-sm-8"><input type="text" class="form-control mydatetimepicker" ng-model="task.starRunTime" ng-max-date="task.starRunTime||defaultDate" placeholder="开始日期" /></div></div><div class="form-group col-sm-6"><label class="control-label col-sm-4">结束时间:</label><div class="col-sm-8"><input type="text" class="form-control mydatetimepicker" ng-model="task.endRunTime" ng-min-date="task.starRunTime" ng-max-date="defaultDate" placeholder="结束日期" /></div></div></div></div><div class="modal-footer"><button type="button" class="btn btn-success" ng-disabled="mymodel.$invalid" ng-click="saveTask()">保 存</button></div></div></div>
</div><table class="table table-hover table-condensed table-bordered" style="width:auto;"><thead><tr style="height: 35px;"><th>任务组</th><th>任务</th><th>CronExpress</th><th>开始时间</th><th>结束时间</th><th>运行状态</th><th>创建时间</th><th>修改时间</th><th>操作</th></tr></thead><tbody class="wait-loaded"><tr ng-repeat="m in list track by m.id"><td>{{m.jobGroup}}</td><td>{{m.jobName}}</td><td>{{m.cronExpress}}</td><td>{{m.starRunTime}}</td><td>{{m.endRunTime}}</td><td>{{m._RunStatus}}</td><td>{{m.createTime}}</td><td>{{m.updateTime}}</td><td><button class="btn btn-success" ng-click="edit(m)">编辑</button><button class="btn btn-danger" ng-click="delete(m)">删除</button></td></tr></tbody>
</table>
<div class="mypager wait-loaded"><ul uib-pagination total-items="search.recordcount" items-per-page="search.pagesize" ng-change="pagechanged()" ng-model="search.pageindex" max-size="7"class="pagination-sm" boundary-links="true" num-pages="search.numpages" boundary-link-numbers="true" first-text="首页" last-text="末页" previous-text="上一页" next-text="下一页"></ul><div class="recordcount">共 {{search.recordcount}} 条</div>
</div>
@section scripts{<script type="text/javascript">$angular.add(function ($scope, $query, $timeout, $sce) {$scope.getHeader = function () { return ["任务组", "任务", "CronExpress", "开始时间", "结束时间", "运行状态", "创建时间", "修改时间"] };$scope._getCsv = function () {var model = _.cloneDeep($scope.search);model.pageSize = 10000000;var promise = $query.post("/webapi/GetTaskList", model, function (response) {var objList = angular.fromJson(response.data);var getArray = [];_.forEach(objList, function (item) {getArray.push({"jobGroup": item.jobGroup,"jobName": item.jobName,"cronExpress": item.cronExpress,"starRunTime": item.starRunTime,"endRunTime": item.endRunTime,"_RunStatus": item._RunStatus,"createTime": item.createTime,"updateTime": item.updateTime});});return getArray;});return promise;};$scope.search = { pageindex: 1, pagesize: 10, gender: "-1", order: 1, status: "-1" };$scope.setorder = function (index) {if (index == math.abs($scope.search.order)) {index = -$scope.search.order;}$scope.search.order = index;$scope.pagechanged(true);};//查询$scope.pagechanged = function (reindex) {if (reindex) {$scope.search.pageindex = 1;}$query.post("/webapi/GetTaskList", $scope.search, function (response) {if (response.status === 200) {$scope.list = response.data;$scope.search.recordcount = response.recordcount;} else {$alert(response.message);}});};$scope.pagechanged();//添加任务$scope.addTask = function () {$("#addmodel").modal("show");$scope.task = { id: -1 };};//保存$scope.saveTask = function () {$query.post("/webapi/AddTaskAsync", $scope.task, function (response) {$("#addmodel").modal("hide");$scope.pagechanged();});};$scope.edit = function (m) {$("#addmodel").modal("show");m.id = m.id;$scope.task = m;}//删除类型$scope.delete = function (m) {m.id = m.id;$scope.task = m;$Confirm("你确认删除吗?该操作不可恢复!", function () {$query.post("/webapi/DelTaskAsync", $scope.task, function (response) {$scope.pagechanged();});});}});</script>
}

View Code

  之后效果就出来了

  

  这个table会调用一个webapi接口获取数据

  

  这个webapi里我们直接调用我们改才ITaskService里分装的方法

  

  这里代码如下:

  

#region 计划任务模块[HttpPost]public Result GetTaskList(){return _taskService.GetTaskList();}[HttpPost]public async Task<Result> AddTaskAsync([FromBody]TaskScheduleModel model){if (model != null && !string.IsNullOrEmpty(model.Id)&&!model.Id.Equals("-1")){return await _taskService.ModifyTaskAsync(model);}return await _taskService.AddTaskAsync(model);}public async Task<Result> DelTaskAsync([FromBody]TaskScheduleModel model){return await _taskService.DelTaskAsync(model);}#endregion

  二.运行测试

  换得添加服务哦

  

  算了,这个运行测试截图不好说明,明天录一个视频说明一下,今天就到这里

  下一章主要说一下权限这块的东西,本来想着今天就写完的,但是有点困了,

  此文章献给我做一年半asp.net core开发的青春岁月,晚安!

  

  

[外包]!采用asp.net core 快速构建小型创业公司后台管理系统(四.quartz 简单配置使用)...相关推荐

  1. ASP.NET Core WebApi构建API接口服务实战演练

    一.ASP.NET Core WebApi课程介绍 人生苦短,我用.NET Core!提到Api接口,一般会想到以前用到的WebService和WCF服务,这三个技术都是用来创建服务接口,只不过Web ...

  2. 【笔记目录1】【jessetalk 】ASP.NET Core快速入门_学习笔记汇总

    当前标签: ASP.NET Core快速入门 共2页: 1 2 下一页  任务50:Identity MVC:DbContextSeed初始化 GASA 2019-03-02 14:09 阅读:16 ...

  3. asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程...

    最近在学习张善友老师的NanoFabric 框架的时了解到Exceptionless : https://exceptionless.com/ !因此学习了一下这个开源框架!下面对Exceptionl ...

  4. 零基础快速开发全栈后台管理系统(Vue3+ElementPlus+Koa2)—项目概述篇(一)

    零基础快速开发全栈后台管理系统(Vue3+ElementPlus+Koa2)-项目概述篇(一) 一.项目开发总体框架 二.项目开发流程 三.项目技术选型

  5. ASP.NET Core 快速入门

    ASP.NET Core 是一个由微软创建的,用于构建 web 应用.API.微服务 的 web 框架.通过本文的学习就能快速的入门ASP.NET Core,对大家的学习或者工作具有一定的参考学习价值 ...

  6. ASP.NET Core快速入门(第4章:ASP.NET Core HTTP介绍)--学习笔记

    点击蓝字关注我们 课程链接:http://video.jessetalk.cn/course/explore 良心课程,大家一起来学习哈! 任务22:课程介绍 1.HTTP 处理过程 2.WebHos ...

  7. 为什么 web 开发人员需要迁移到. NET Core, 并使用 ASP.NET Core MVC 构建 web 和 API

    2018 .NET开发者调查报告: .NET Core 是怎么样的状态,这里我们看到了还有非常多的.net开发人员还在观望,本文给大家一个建议.这仅代表我的个人意见, 我有充分的理由推荐.net 程序 ...

  8. WTM:ASP.NET Core快速开发利器!

    不少程序员朋友应该都有这个想法,接接私活,赚赚外快,但是从零开发一套系统并不容易,今天给大家推荐一款开箱即用的通用后台管理系统. 一个能够让程序猿快速开发的炒鸡脚手架,采用.NET Core开源框架! ...

  9. ASP.NET Core快速入门(第3章:依赖注入)--学习笔记

    点击蓝字关注我们 课程链接:http://video.jessetalk.cn/course/explore 良心课程,大家一起来学习哈! 任务16:介绍 1.依赖注入概念详解 从UML和软件建模来理 ...

最新文章

  1. html文档表示表格的标记,【单选题】在HTML文档中用于表示表格的标记对是( )...
  2. 【微信开发】微信开发 之 开启开发模式
  3. 微信腾讯会议进行视频面试,如何使用腾讯会议进行视频面试?
  4. ORACLE数据库实现自增的方式
  5. Midway Serverless 2.0,一体化让前端研发再次提效
  6. WinDbg学习笔记(一)--认识WinDbg
  7. tomcat中设置Java 客户端程序的http(https)访问代理
  8. 密码学研究-加密解密
  9. 什么是数据治理的方法论
  10. 只知道CS224N?斯坦福最新推出NLU公开课CS224U
  11. 研究多个基因间相互作用的频域方法
  12. 你知道吗?世界上绝美神奇的25条路
  13. python网课答案查询_网课答案查询助手v1.0 官方版
  14. 服务器备案全流程超级详细
  15. 【AI视野·今日CV 计算机视觉论文速览 第228期】Tue, 29 Jun 2021
  16. 电视台工作计算机管理,电视台工作岗位有哪些
  17. 树洞程序php,Anonymous – 秘密 PHP树洞程序
  18. 服务器显示器白屏,电脑显示器白屏的原因以及处理方法
  19. 北京:一个大学生每年要花多少钱
  20. 摸鱼还是学习?来看看这些网站吧!

热门文章

  1. 集合框架(去除ArrayList集合中的重复字符串元素案例2)
  2. Ubuntu打印机控制命令笔记
  3. exp/imp迁移表
  4. VMM2012应用指南之11-将虚拟机转换为模板
  5. 学习:配置hibernate
  6. 安装zabbix服务器端
  7. 8月8日白暨豚宣告灭绝
  8. IAR常用快捷键及技巧
  9. 求最大子数组(贪心算法)
  10. 实现类似美团的下拉分级式菜单