您的位置:首页 > 编程语言 > ASP

Asp.Net Core2.0 基于QuartzNet任务管理系统

2018-03-01 16:47 309 查看
Quartz.NET官网地址:https://www.quartz-scheduler.net/

Quartz.NET文档地址:https://www.quartz-scheduler.net/documentation/index.html

Quartz.NET
是一个开源的作业调度框架,是
OpenSymphony
Quartz API
的.NET移植,它用C#写成,可用于
winform
asp.net
应用中。它提供了巨大的灵活性而不牺牲简单性。你能够用它来为执行一个作业而创建简单的或复杂的调度。它有很多特征,如:数据库支持,集群,插件,支持
cron-like
表达式等等。

现在
Quartz.NET3.0
已支持
Asp.Net Core
,3.0新功能如下:

新功能

具有异步/等待支持的基于任务的作业,内部以异步/等待方式工作

支持.NET Core / netstandard 2.0和.NET Framework 4.5.2及更高版本

通过提供程序名称
SQLite-Microsoft
支持
Microsoft.Data.Sqlite
,旧的提供程序
SQLite
也仍然有效

增加了
SQL Server
内存优化表和
Quartz.Impl.AdoJobStore.UpdateLockRowSemaphoreMOT
的初步支持

Common.Logging
从相关性中删除

ILMerge
进程中删除的C5集合不再需要

在插件启动时添加对作业调度XML文件的急切验证的支持

TimeZoneUtil
中添加对额外的自定义时区解析器功能的支持

变化

作业和插件现在位于独立的程序集
NuGet
Quartz.Jobs
Quartz.Plugins


ADO.NET提供者名称已被简化,提供者名称没有版本,例如
SqlServer-20 => SqlServer


API方法已被重新使用,主要使用
IReadOnlyCollection
,这隐藏了两个
HashSet
s和List小号

LibLog
一直隐藏于内部(ILog等),就像它原本打算的那样

SimpleThreadPool
消失了,旧的拥有的线程消失了

调度程序方法已更改为基于任务,请记住等待它们

IJob
接口现在返回一个任务

一些
IList
属性已更改为
IReadOnlyList
以正确反映意图

SQL Server CE
支持已被删除

DailyCalendar
现在将日期时间用于排除的日期,并具有
ISet
接口来访问它们

IObjectSerializer
有新的方法,
void Initialize()
,必须实现

IInterruptableJob
取消了上下文的
CancellationToken


Quartz API的关键接口和类是

IScheduler
- 与调度程序交互的主要API。

IJob
- 您希望由调度程序执行的组件实现的接口。

IJobDetail
- 用于定义作业的实例。

ITrigger
- 定义执行给定Job的时间表的组件。

JobBuilder
- 用于定义/构建定义作业实例的
JobDetail
实例。

TriggerBuilder
- 用于定义/构建触发器实例

一、Quartz.NET基本使用

1、新建Asp.Net Core 项目,使用NuGet添加Quartz,或使用程序包管理器引用,命令如下:

Install-Package Quartz


如果你想添加JSON序列化,只需要以同样的方式添加
Quartz.Serialization.Json
包。

2、简单实例,代码如下:

using Five.QuartzNetJob.ExecuteJobTask.Service;
using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Threading.Tasks;

namespace Five.QuartzNetJob.Web.Controllers
{
public class TestTask
{
public async Task StartTestAsync()
{
try
{
// 从工厂中获取调度程序实例
NameValueCollection props = new NameValueCollection
{
{ "quartz.serializer.type", "binary" }
};
StdSchedulerFactory factory = new StdSchedulerFactory(props);
IScheduler scheduler = await factory.GetScheduler();

// 开启调度器
await scheduler.Start();

// 定义这个工作,并将其绑定到我们的IJob实现类
IJobDetail job = JobBuilder.Create<HelloJob>()
.WithIdentity("job1", "group1")
.Build();

// 触发作业立即运行,然后每10秒重复一次,无限循环
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("trigger1", "group1")
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(10)
.RepeatForever())
.Build();

// 告诉Quartz使用我们的触发器来安排作业
await scheduler.ScheduleJob(job, trigger);

// 等待60秒
await Task.Delay(TimeSpan.FromSeconds(60));

// 关闭调度程序
await scheduler.Shutdown();
}
catch (SchedulerException se)
{
await Console.Error.WriteLineAsync(se.ToString());
}
}
}
}


HelloJob内容如下:

using Quartz;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace Five.QuartzNetJob.ExecuteJobTask.Service
{
public class HelloJob : IJob
{
public  Task Execute(IJobExecutionContext context)
{
Console.Out.WriteLineAsync("Greetings from HelloJob!");
return Task.CompletedTask;
}
}
}


执行效果如下:

using QuartzNet.Entity;
using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Specialized;
using System.Threading.Tasks;
using Five.QuartzNetJob.Utils.Tool;
using System.Reflection;
using System.Collections.Generic;

namespace QuartzNet3.Core
{
/// <summary>
/// 任务调度中心
/// </summary>
public class SchedulerCenter
{
/// <summary>
/// 任务调度对象
/// </summary>
public static readonly SchedulerCenter Instance;
static SchedulerCenter()
{
Instance = new SchedulerCenter();
}
private Task<IScheduler> _scheduler;

/// <summary>
/// 返回任务计划(调度器)
/// </summary>
/// <returns></returns>
private Task<IScheduler> Scheduler
{
get
{
if (this._scheduler != null)
{
return this._scheduler;
}
// 从Factory中获取Scheduler实例
NameValueCollection props = new NameValueCollection
{
{ "quartz.serializer.type", "binary" },
//以下配置需要数据库表配合使用,表结构sql地址:https://github.com/quartznet/quartznet/tree/master/database/tables
//{ "quartz.jobStore.type","Quartz.Impl.AdoJobStore.JobStoreTX, Quartz"},
//{ "quartz.jobStore.driverDelegateType","Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz"},
//{ "quartz.jobStore.tablePrefix","QRTZ_"},
//{ "quartz.jobStore.dataSource","myDS"},
//{ "quartz.dataSource.myDS.connectionString",AppSettingHelper.MysqlConnection},//连接字符串
//{ "quartz.dataSource.myDS.provider","MySql"},
//{ "quartz.jobStore.useProperties","true"}

};
StdSchedulerFactory factory = new StdSchedulerFactory(props);
return this._scheduler = factory.GetScheduler();
}
}

/// <summary>
/// 运行指定的计划(映射处理IJob实现类)
/// </summary>
/// <param name="jobGroup">任务分组</param>
/// <param name="jobName">任务名称</param>
/// <returns></returns>
public async Task<BaseQuartzNetResult> RunScheduleJob<T>(string jobGroup, string jobName) where T : ScheduleManage
{
BaseQuartzNetResult result;
//开启调度器
await this.Scheduler.Result.Start();
//创建指定泛型类型参数指定的类型实例
T t = Activator.CreateInstance<T>();
//获取任务实例
ScheduleEntity scheduleModel = t.GetScheduleModel(jobGroup, jobName);
//添加任务
var addResult = AddScheduleJob(scheduleModel).Result;
if (addResult.Code == 1000)
{
scheduleModel.Status = EnumType.JobStatus.已启用;
t.UpdateScheduleStatus(scheduleModel);
//用给定的密钥恢复(取消暂停)IJobDetail
await this.Scheduler.Result.ResumeJob(new JobKey(jobName, jobGroup));
result = new BaseQuartzNetResult
{
Code = 1000,
Msg = "启动成功"
};
}
else
{
result = new BaseQuartzNetResult
{
Code = -1
};
}
return result;
}
/// <summary>
/// 添加一个工作调度(映射程序集指定IJob实现类)
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
private async Task<BaseQuartzNetResult> AddScheduleJob(ScheduleEntity m)
{
var result = new BaseQuartzNetResult();
try
{

//检查任务是否已存在
var jk = new JobKey(m.JobName, m.JobGroup);
if (await this.Scheduler.Result.CheckExists(jk))
{
//删除已经存在任务
await this.Scheduler.Result.DeleteJob(jk);
}
//反射获取任务执行类
var jobType = FileHelper.GetAbsolutePath(m.AssemblyName, m.AssemblyName + "." + m.ClassName);
// 定义这个工作,并将其绑定到我们的IJob实现类
IJobDetail job = new JobDetailImpl(m.JobName, m.JobGroup, jobType);
//IJobDetail job = JobBuilder.CreateForAsync<T>().WithIdentity(m.JobName, m.JobGroup).Build();
// 创建触发器
ITrigger trigger;
//校验是否正确的执行周期表达式
if (!string.IsNullOrEmpty(m.Cron) && CronExpression.IsValidExpression(m.Cron))
{
trigger = CreateCronTrigger(m);
}
else
{
trigger = CreateSimpleTrigger(m);
}

// 告诉Quartz使用我们的触发器来安排作业
await this.Scheduler.Result.ScheduleJob(job, trigger);

result.Code = 1000;
}
catch (Exception ex)
{
await Console.Out.WriteLineAsync(string.Format("添加任务出错{0}", ex.Message));
result.Code = 1001;
result.Msg = ex.Message;
}
return result;
}
/// <summary>
/// 运行指定的计划(泛型指定IJob实现类)
/// </summary>
/// <param name="jobGroup">任务分组</param>
/// <param name="jobName">任务名称</param>
/// <returns></returns>
public async Task<BaseQuartzNetResult> RunScheduleJob<T, V>(string jobGroup, string jobName) where T : ScheduleManage, new() where V : IJob
{
BaseQuartzNetResult result;
//开启调度器
await this.Scheduler.Result.Start();
//创建指定泛型类型参数指定的类型实例
T t = Activator.CreateInstance<T>();
//获取任务实例
ScheduleEntity scheduleModel = t.GetScheduleModel(jobGroup, jobName);
//添加任务
var addResult = AddScheduleJob<V>(scheduleModel).Result;
if (addResult.Code == 1000)
{
scheduleModel.Status = EnumType.JobStatus.已启用;
t.UpdateScheduleStatus(scheduleModel);
//用给定的密钥恢复(取消暂停)IJobDetail
await this.Scheduler.Result.ResumeJob(new JobKey(jobName, jobGroup));
result = new BaseQuartzNetResult
{
Code = 1000,
Msg = "启动成功"
};
}
else
{
result = new BaseQuartzNetResult
{
Code = -1
};
}
return result;
}
/// <summary>
/// 添加任务调度(指定IJob实现类)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="m"></param>
/// <returns></returns>
private async Task<BaseQuartzNetResult> AddScheduleJob<T>(ScheduleEntity m) where T : IJob
{
var result = new BaseQuartzNetResult();
try
{

//检查任务是否已存在
var jk = new JobKey(m.JobName, m.JobGroup);
if (await this.Scheduler.Result.CheckExists(jk))
{
//删除已经存在任务
await this.Scheduler.Result.DeleteJob(jk);
}
//反射获取任务执行类
// var jobType = FileHelper.GetAbsolutePath(m.AssemblyName, m.AssemblyName + "." + m.ClassName);
// 定义这个工作,并将其绑定到我们的IJob实现类
//IJobDetail job = new JobDetailImpl(m.JobName, m.JobGroup, jobType);
IJobDetail job = JobBuilder.CreateForAsync<T>().WithIdentity(m.JobName, m.JobGroup).Build();
// 创建触发器
ITrigger trigger;
//校验是否正确的执行周期表达式
if (!string.IsNullOrEmpty(m.Cron) && CronExpression.IsValidExpression(m.Cron))
{
trigger = CreateCronTrigger(m);
}
else
{
trigger = CreateSimpleTrigger(m);
}

// 告诉Quartz使用我们的触发器来安排作业
await this.Scheduler.Result.ScheduleJob(job, trigger);

result.Code = 1000;
}
catch (Exception ex)
{
await Console.Out.WriteLineAsync(string.Format("添加任务出错", ex.Message));
result.Code = 1001;
result.Msg = ex.Message;
}
return result;
}
/// <summary>
/// 暂停指定的计划
/// </summary>
/// <param name="jobGroup">任务分组</param>
/// <param name="jobName">任务名称</param>
/// <param name="isDelete">停止并删除任务</param>
/// <returns></returns>
public BaseQuartzNetResult StopScheduleJob<T>(string jobGroup, string jobName, bool isDelete = false) where T : ScheduleManage, new()
{
BaseQuartzNetResult result;
try
{
this.Scheduler.Result.PauseJob(new JobKey(jobName, jobGroup));
if (isDelete)
{
Activator.CreateInstance<T>().RemoveScheduleModel(jobGroup, jobName);
}
result = new BaseQuartzNetResult
{
Code = 1000,
Msg = "停止任务计划成功!"
};
}
catch (Exception ex)
{
result = new BaseQuartzNetResult
{
Code = -1,
Msg = "停止任务计划失败"
};
}
return result;
}
/// <summary>
/// 恢复运行暂停的任务
/// </summary>
/// <param name="jobName">任务名称</param>
/// <param name="jobGroup">任务分组</param>
public async void ResumeJob(string jobName, string jobGroup)
{
try
{
//检查任务是否存在
var jk = new JobKey(jobName, jobGroup);
if (await this.Scheduler.Result.CheckExists(jk))
{
//任务已经存在则暂停任务
await this.Scheduler.Result.ResumeJob(jk);
await Console.Out.WriteLineAsync(string.Format("任务“{0}”恢复运行", jobName));
}
}
catch (Exception ex)
{
await Console.Out.WriteLineAsync(string.Format("恢复任务失败!{0}", ex));
}
}

/// <summary>
/// 停止任务调度
/// </summary>
public async void StopScheduleAsync()
{
try
{
//判断调度是否已经关闭
if (!this.Scheduler.Result.IsShutdown)
{
//等待任务运行完成
await this.Scheduler.Result.Shutdown();
await Console.Out.WriteLineAsync("任务调度停止!");
}
}
catch (Exception ex)
{
await Console.Out.WriteLineAsync(string.Format("任务调度停止失败!", ex));
}
}
/// <summary>
/// 创建类型Simple的触发器
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
private ITrigger CreateSimpleTrigger(ScheduleEntity m)
{
//作业触发器
if (m.RunTimes > 0)
{
return TriggerBuilder.Create()
.WithIdentity(m.JobName, m.JobGroup)
.StartAt(m.BeginTime)//开始时间
.EndAt(m.EndTime)//结束数据
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(m.IntervalSecond)//执行时间间隔,单位秒
.WithRepeatCount(m.RunTimes))//执行次数、默认从0开始
.ForJob(m.JobName, m.JobGroup)//作业名称
.Build();
}
else
{
return TriggerBuilder.Create()
.WithIdentity(m.JobName, m.JobGroup)
.StartAt(m.BeginTime)//开始时间
.EndAt(m.EndTime)//结束数据
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(m.IntervalSecond)//执行时间间隔,单位秒
.RepeatForever())//无限循环
.ForJob(m.JobName, m.JobGroup)//作业名称
.Build();
}

}
/// <summary>
/// 创建类型Cron的触发器
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
private ITrigger CreateCronTrigger(ScheduleEntity m)
{
// 作业触发器
return TriggerBuilder.Create()
.WithIdentity(m.JobName, m.JobGroup)
.StartAt(m.BeginTime)//开始时间
.EndAt(m.EndTime)//结束时间
.WithCronSchedule(m.Cron)//指定cron表达式
.ForJob(m.JobName, m.JobGroup)//作业名称
.Build();
}
}
}


View Code
总结:

开发已个小项目搞了好久才搞完,期间零零散散的开发,还是太懒散了!

平时积累不够,还是太菜了!!!!!

欢迎各位大佬指导指定我这个新人!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐