任务调度之持久化(基于Quartz.net)
上一篇我们了解了任务调度及他的远端管理方式,传送门:任务调度及远端管理(基于Quartz.net)
这篇我们要完成任务调度的持久化功能,即新增修改删除之类的功能,这必须得要有的,不然都不知道后台都有什么作业在跑
一、Job的CURD
1.1 、新建Job表
CREATE TABLE [dbo].[Job](
[Id] [uniqueidentifier] NOT NULL,
[GroupName] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[JobName] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[TriggerName] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[Cron] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[TriggerState] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[StartTime] [datetime] NULL,
[EndTime] [datetime] NULL,
[PreTime] [datetime] NULL,
[NextTime] [datetime] NULL,
[Description] [nvarchar](200) COLLATE Chinese_PRC_CI_AS NULL,
[CreateTime] [datetime] NULL,
CONSTRAINT [PK_Job] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] GO
1.2、控制器还是用上一篇的HelloJobController,改一下
public class HelloJobController : Controller
{
private IJobApplication jobApplication; public HelloJobController(IJobApplication jobApplication)
{
this.jobApplication = jobApplication;
} [Route("Jobs/{PageIndex=1}")]
public ActionResult Index(string PageIndex)
{
Page page = new Page();
page.PageIndex = PageIndex.ToInt(); var model = new JobPageViewModel();
var soure = this.jobApplication.GetPage(page, t => t.CreateTime); model.Items = Mapper.Map<List<JobViewModel>>(soure.Item2);
model.Total = soure.Item1;
model.Page = page; return View(model);
} [HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Add(JobCURequest entity)
{
this.jobApplication.Add(new JobCURequest()
{
Id = Guid.NewGuid(),
GroupName = entity.GroupName,
JobName = entity.JobName,
TriggerName = entity.TriggerName,
Cron = entity.Cron,
TriggerState = Quartz.TriggerState.None.ToString()
}); return RedirectToAction("Index");
} [HttpGet]
public ActionResult Delete(string id)
{
this.jobApplication.Delete(Guid.Parse(id));
return RedirectToAction("Index");
} [HttpGet]
public ActionResult Edit(Guid id)
{
var soure = this.jobApplication.Get(id);
return Json(soure, JsonRequestBehavior.AllowGet);
} [HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(JobCURequest entity)
{
this.jobApplication.Update(new JobCURequest()
{
Id = entity.Id,
GroupName = entity.GroupName,
JobName = entity.JobName,
TriggerName = entity.TriggerName,
Cron = entity.Cron,
TriggerState = Quartz.TriggerState.None.ToString()
}); return RedirectToAction("Index");
}73 }
可以看到我们新加了IJobApplication的注入,以及Index、Add、Delete、Edit(2个)5个方法
至于里边的实现就是我们上一个系列写好的功能,详细情况请点击传送门:架构设计
1.3、 视图View也要改一下
@model Presentation.MVC.Models.JobPageViewModel
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Bootstrap.cshtml";
} <br />
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#collapseOne" id="actionType">
新增作业
</a>
</h4>
</div>
<div id="collapseOne" class="panel-collapse collapse">
<div class="panel-body">
@using (Html.BeginForm("Add", "HelloJob", null, FormMethod.Post, new { @id = "formHelloJob", @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken() <div class="form-group">
<label for="LoginName" class="col-sm-2 control-label">群组</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="GroupName" id="GroupName"
placeholder="请输入群组" />
</div>
</div>
<div class="form-group">
<label for="Password" class="col-sm-2 control-label">作业名称</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="JobName" id="JobName"
placeholder="请输入作业名称" />
</div>
</div>
<div class="form-group">
<label for="Password" class="col-sm-2 control-label">触发器名称</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="TriggerName" id="TriggerName"
placeholder="请输入触发器名称" />
</div>
</div>
<div class="form-group">
<label for="Password" class="col-sm-2 control-label">执行计划</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="Cron" id="Cron"
placeholder="请输入执行计划" />
</div>
</div>
<div class="form-group">
<label for="Password" class="col-sm-2 control-label">描述</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="Description" id="Description"
placeholder="请输入描述" />
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<input type="hidden" name="Id" id="Id" />
<button type="submit" class="btn btn-default">提交</button>
</div>
</div>
}
</div>
</div>
</div> <div style=" margin-bottom:5px;">
<a id="btnRun" class="btn btn-default" href="#" role="button">执行</a>
<a id="btnPause" class="btn btn-default" href="#" role="button">暂停</a>
<a id="btnResume" class="btn btn-default" href="#" role="button">恢复</a> <a id="btnEdit" class="btn btn-default" href="#" role="button" style=" margin-left:10px">修改</a>
<a id="btnDel" class="btn btn-default" href="#" role="button">删除</a>
</div>
<table id="list" class="table table-striped table-bordered table-hover table-condensed">
<thead>
<tr>
<th><input type="checkbox" class="chkAll" /></th>
<th>序号</th>
<th>群组</th>
<th>作业名称</th>
<th>触发器名称</th>
<th>执行计划</th>
<th>描述</th>
<th>开始时间</th>
<th>结束时间</th>
<th>上次执行</th>
<th>下次执行</th>
<th>状态</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Items)
{
<tr>
<td><input type="checkbox" name="subBox" value="@item.Id" /></td>
<td>@item.RowNumber</td>
<td>@item.GroupName</td>
<td>@item.JobName</td>
<td>@item.TriggerName</td>
<td>@item.Cron</td>
<td>@item.Description</td>
<td>@item.StartTime</td>
<td>@item.EndTime</td>
<td>@item.PreTime</td>
<td>@item.NextTime</td>
<td>@item.TriggerState</td>
</tr>
}
</tbody>
</table> <ul class="pagination">
<li><a href="/HelloJob/@Model.PrePage">«</a></li>
@for (int index = 1; index <= Model.TotalPage; index++)
{
if (Model.Page.PageIndex == index)
{
<li class="active"><a href="/HelloJob/@index">@index</a></li>
}
else
{
<li><a href="/HelloJob/@index">@index</a></li>
}
}
<li><a href="/HelloJob/@Model.NextPage">»</a></li>
</ul> <script type="text/javascript">
$(function () {
$(".chkAll").click(function () {
if (this.checked) {
$('input[name="subBox"]').attr("checked", this.checked);
} else {
$('input[name="subBox"]').removeAttr("checked");
}
}); $("#btnEdit").click(function () {
var id = GetChooseIds();
if (id == undefined || id == null || id == "") return; $.ajax({
url: "/HelloJob/Edit/" + id,
type: "GET",
dataType: 'json',
success: function (result) {
$("#Id").val(result.Id);
$("#GroupName").val(result.GroupName);
$("#JobName").val(result.JobName);
$("#TriggerName").val(result.TriggerName);
$("#Cron").val(result.Cron);
$("#Description").val(result.Description); $('#collapseOne').collapse('show');
$("#formHelloJob").attr("action", "/HelloJob/Edit");
$("#actionType").html("修改作业");
},
error: function (e) {
alert(e);
}
});
}); $("#btnDel").click(function () {
var id = GetChooseIds();
if (id == undefined || id == null || id == "") return; CreateDeleteWindow(function () {
location.href = "/HelloJob/Delete/" + id;
});
}); $("#btnRun").click(function () {
var id = GetChooseIds();
if (id == undefined || id == null || id == "") return; CreateRunWindow(function () {
location.href = "/HelloJob/Run/" + id;
});
}); $("#btnPause").click(function () {
var id = GetChooseIds();
if (id == undefined || id == null || id == "") return; CreatePauseWindow(function () {
location.href = "/HelloJob/Pause/" + id;
});
}); $("#btnResume").click(function () {
var id = GetChooseIds();
if (id == undefined || id == null || id == "") return; CreateResumeWindow(function () {
location.href = "/HelloJob/Resume/" + id;
});
}); function GetChooseIds() {
var id = "";
$('input[name="subBox"]').each(function () {
id = $(this).attr("value");
}); return id;
}
});
</script>
1.4、界面代码就完成了,我们去看看


完全没问题,下面我们来完成 执行、暂停、恢复三个操作作业的按钮功能
二、作业管理
2.1、HelloJobHelper改一下,名称我也改了(JobHelper)

2.2、HelloJobController加入上边三个功能
public ActionResult Run(Guid id)
{
var success = this.jobApplication.Update(new JobCURequest()
{
Id = id,
TriggerState = Quartz.TriggerState.Normal.ToString()
}); if (success)
{
var entity = this.jobApplication.Get(id);
JobHelper.Run(entity);
} return RedirectToAction("Index", "HelloJob");
} public ActionResult Pause(Guid id)
{
var success = this.jobApplication.Update(new JobCURequest()
{
Id = id,
TriggerState = Quartz.TriggerState.Paused.ToString()
}); if (success)
{ var entity = this.jobApplication.Get(id);
JobHelper.Pause(entity);
}
return RedirectToAction("Index", "HelloJob");
} public ActionResult Resume(Guid id)
{
var success = this.jobApplication.Update(new JobCURequest()
{
Id = id,
TriggerState = Quartz.TriggerState.Normal.ToString()
}); if (success)
{
var entity = this.jobApplication.Get(id);
JobHelper.Resume(entity);
} return RedirectToAction("Index", "HelloJob");
}
2.3、好了,现在开启服务端

2.4、执行

2.5、暂停

2.6、恢复

好了,基本上就是这些了
任务调度之持久化(基于Quartz.net)的更多相关文章
- 【Quartz】Quartz存储与持久化-基于quartz.properties的配置
林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 一. Quartz存储与持久化 Quartz提供两种基本作业存储类型.第一种类型叫做RAM ...
- 004-Quartz存储与持久化-基于quartz.properties的配置
一.概述 Quartz提供两种基本作业存储类型.第一种类型叫做RAMJobStore,第二种类型叫做JDBC作业存储.在默认情况下Quartz将任务调度的运行信息保存在内存中,这种方法提供了最佳的性能 ...
- 任务调度之集群(基于Quartz.net)
上一篇我们完成了任务调度的持久化,传送门:任务调度之持久化(基于Quartz.net) 这篇我们来完成Quartz.net的一个比较优秀的功能,即集群:集群可以提高任务调度服务的容灾性, 当一个节点宕 ...
- RDIFramework.NET框架基于Quartz.Net实现任务调度详解及效果展示
在上一篇Quartz.Net实现作业定时调度详解,我们通过实例代码详细讲解与演示了基于Quartz.NET开发的详细方法.本篇我们主要讲述基于RDIFramework.NET框架整合Quartz.NE ...
- Window服务基于Quartz.Net组件实现定时任务调度(二)
前言: 在上一章中,我们通过利用控制台实现定时任务调度,已经大致了解了如何基于Quartz.Net组件实现任务,至少包括三部分:job(作业),trigger(触发器),scheduler(调度器). ...
- 一行代码完成定时任务调度,基于Quartz的UI可视化操作组件 GZY.Quartz.MUI
前言 之前发布过第一个版本,有兴趣的可以去看看: NET Core 基于Quartz的UI可视化操作组件 GZY.Quartz.MUI 简介 GitHub开源地址:l2999019/GZY.Quart ...
- 基于Quartz实现简单的定时发送邮件
一.什么是Quartz Quartz 是一个轻量级任务调度框架,只需要做些简单的配置就可以使用:它可以支持持久化的任务存储,即使是任务中断或服务重启后,仍可以继续运行.Quartz既可以做为独立的应用 ...
- Quartz.NET总结(五)基于Quartz.net 的开源任务管理平台
前面总结了很多,关于Quartz.net 的文章,介绍了如何使用Quartz.net.不清楚的朋友,可以看我之前的系列文章,http://www.cnblogs.com/zhangweizhong/c ...
- Java 基于quartz实现定时 之二(XML方式配置)
<!-- 在spring核心配置文件中进行如下配置 --> <!-- Spring基于quartz定时任务 --> <bean id="triggerByBea ...
随机推荐
- Unity编程标准导引-3.2 MonoBehavior 组件父类重构
本文为博主原创文章,欢迎转载.请保留博主链接:http://blog.csdn.net/andrewfan 3.2MonoBehavior 组件父类重构 为了让我们的组件类用起来更方便,我们将上一节的 ...
- 利用nodejs监控文件变化并使用sftp上传到服务器
很久没写博客了,因为最近在用react+express做一个自己的工具型网站(其实就是夺宝岛抢拍器) 然后因为经常要改动,而且又要放到服务器上进行测试.总是要webpack,然后手动把文件上传上去,不 ...
- (C#)xml的简单理解创建和读取
xml知识点清理:一.文档规则 1.区分大小写. 2.属性值必须加引号(单引号.双引号都可以),一般情况下建议使用使用双引号. 3.所有标记必须有结束符号. 4.所有空标记必须关闭. 5.必须有且仅有 ...
- Alamofire源码解读系列(一)之概述和使用
尽管Alamofire的github文档已经做了很详细的说明,我还是想重新梳理一遍它的各种用法,以及这些方法的一些设计思想 前言 因为之前写过一个AFNetworking的源码解读,所以就已经比较了解 ...
- JavaScript中值类型和引用类型的区别
JavaScript的数据类型分为两类:原始类型和对象类型.其中,原始类型包括:数字.字符串和布尔值.此外,JavaScript中还有两个特殊的原始值:null和undefined,它们既不是数字也不 ...
- 中间自适应,左右定宽的两种经典布局 ---- 圣杯布局 VS 双飞翼布局
一.引子 最近学了些js框架,小有充实感,又深知如此节奏的前提需得基础扎实,于是回头想将原生CSS和Javascript回顾总结一番,先从CSS起,能集中它的就在基础的布局上,便查阅了相关资料,将布局 ...
- POJ 2396 Budget 有上下界的网络流
POJ 2396 Budget 题意简述:给定矩阵(每个元素都是非负整数)各行各列的和,并且限制其中的某些元素,给出一个可行解,特殊评测.矩阵规模小于200*20. 网络流的模型是显而易见的,不过对 ...
- js或者php浮点数运算产生多位小数的理解
<?php $f = 0.58; var_dump(intval($f * 100)); //为啥输出57 ?> 首先我们要知道浮点数的表示(IEEE 754): 浮点数, 以64位的长度 ...
- jiayuan
8.2=http://files.cnblogs.com/files/bqh10086/jiayuan8.2pack.zip
- setTimeout的妙用2——防止循环超时
上个周日,介绍了如何使用setTimeout代替setInterval进行间歇调用,这个周日,继续来讲<JavaScript高级程序设计>这本书里面,对于setTimeout的另一种妙用- ...