准备工作
1、创建.net core 项目(注:此处创建的是webapi项目)
2、nuget 搜索并安装Quartz
Quartz相关API了解参见
https://www.quartz-scheduler.net/
https://quartznet.sourceforge.io/apidoc/1.0/html/
定时任务功能实现
1、创建定时任务业务类SyncJon.cs,示例代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.IO;
using Quartz;
namespace AutoOS.EuipmentManage.Common
{
/// <summary>
/// 定时执行的任务JOB
/// </summary>
public class SyncJob:IJob
{
private readonly SystemManageAdapter systemManageAdapter;
public SyncJob(SystemManageAdapter systemManageAdapter)
{
this.systemManageAdapter = systemManageAdapter;
}
/// <summary>
/// 定时执行的任务事务处理
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public async Task Execute(IJobExecutionContext context)
{
//需要处理的业务代码
//数据同步处理
await Console.Out.WriteLineAsync($"{DateTime.Now:HH:mm:ss}--数据同步完成!");
}
}
}
2、创建自定义Job工厂SyncJobFactory.cs,代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Quartz;
using Quartz.Spi;
namespace AutoOS.EuipmentManage.Common
{
/// <summary>
/// 自定义Job工厂
/// </summary>
public class SyncJobFactory :IJobFactory
{
//IServiceProvider 为了注入自定义job服务,job服务构造参数实例化(此处是SyncJob.cs)及获取自定义JOB的实例
private readonly IServiceProvider _serviceProvider;
/// <summary>
///
/// </summary>
/// <param name="serviceProvider"></param>
public SyncJobFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
}
/// <summary>
///
/// </summary>
/// <param name="bundle"></param>
/// <param name="scheduler"></param>
/// <returns></returns>
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
//获取自定义JOB的实例
return _serviceProvider.GetRequiredService(bundle.JobDetail.JobType) as IJob;
}
/// <summary>
///
/// </summary>
/// <param name="job"></param>
public void ReturnJob(IJob job)
{
}
}
}
3、创建定时任务调度中心SchedulerCenter.cs,参考代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
using Quartz.Spi;
namespace AutoOS.EuipmentManage.Common
{
/// <summary>
/// 任务调度中心
/// </summary>
public class SchedulerCenter
{
private readonly IJobFactory _jobFactory;
private readonly ISchedulerFactory _schedulerFactory;
private IScheduler _scheduler;
public SchedulerCenter(IJobFactory jobFactory, ISchedulerFactory schedulerFactory)
{
_jobFactory = jobFactory;
_schedulerFactory = schedulerFactory;
}
public async void StartScheduler()
{
_scheduler = await _schedulerFactory.GetScheduler();
// 替换默认工厂
_scheduler.JobFactory = this._jobFactory;
//创建任务并将其与SyncJob任务相关联
IJobDetail job = JobBuilder.Create<SyncJob>()
.WithIdentity("SyncJob", "SyncJobGroup")
.Build();
//配置触发条件:当即触发做业运行,而后每10秒重复一次
ITrigger trigger = TriggerBuilder.Create()
.WithCronSchedule("0 30 10 * * ? ")//每天定点 10点30执行任务
.WithIdentity("SyncJob", "SyncJobGroup")
//.StartNow()
//.WithSimpleSchedule(x => x
// .WithIntervalInSeconds(10) //每10秒执行一次任务
// .RepeatForever())
.Build();
//可创建多个job与trigger;并进行关联
//将做业与触发条件添加到调度实例并进行关联
await _scheduler.ScheduleJob(job, trigger);
//打开调度器
await _scheduler.Start();
}
public void StopScheduler()
{
_scheduler?.Shutdown(true).Wait(30000);
_scheduler = null;
}
}
}
4、在Startup.cs的ConfigureServices中注入相关代码
services.AddSingleton<SchedulerCenter>();//注入调度中心
//注入Quartz任何工厂及调度工厂
services.AddSingleton<IJobFactory, SyncJobFactory>();
services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();
services.AddTransient<SyncJob>();//注入SyncJob
5、在Starup.cs的Configure中,使用IApplicationLifetime启动定时任务;参考代码如下
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, Microsoft.AspNetCore.Hosting.IApplicationLifetime applicationLifetime)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseStaticFiles(new StaticFileOptions { ServeUnknownFileTypes = true });//设置不限制content-type
//启动定时任务—设备管理、测点数据、测点异常数据任务
var quartz = app.ApplicationServices.GetRequiredService<SchedulerCenter>();
applicationLifetime.ApplicationStarted.Register(() =>
{
quartz.StartScheduler(); //项目启动后启动调度中心
});
applicationLifetime.ApplicationStopped.Register(() =>
{
quartz.StopScheduler(); //项目中止后关闭调度中心
});
}
6、最后使用CLI(cmd命令方式)启动项目运行
使用管理员身份运行命令提示符,使用cd命令,进入发布包所在的文件夹,最后使用
dotnet xxxx.dll 启动发布的程序(xxxx.dll为发布的程序的名称)
附:Quartz Corn 表达式使用详解
官方参照:http://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/crontrigger.html
cron expressions 整体上还是非常容易理解的,只有一点需要注意:"?"号的用法,看下文可以知道“?”可以用在 day of month 和 day of week中,他主要是为了解决如下场景,如:每月的1号的每小时的31分钟,正确的表达式是:* 31 * 1 * ?,而不能是:* 31 * 1 * *,因为这样代表每周的任意一天。
/*
由7段构成:秒 分 时 日 月 星期 年(可选)
"-" :表示范围 MON-WED表示星期一到星期三
"," :表示列举 MON,WEB表示星期一和星期三
"*" :表是“每”,每月,每天,每周,每年等
"/" :表示增量:0/15(处于分钟段里面) 每15分钟,在0分以后开始,3/20 每20分钟,从3分钟以后开始
"?" :只能出现在日,星期段里面,表示不指定具体的值
"L" :只能出现在日,星期段里面,是Last的缩写,一个月的最后一天,一个星期的最后一天(星期六)
"W" :表示工作日,距离给定值最近的工作日
"#" :表示一个月的第几个星期几,例如:"6#3"表示每个月的第三个星期五(1=SUN...6=FRI,7=SAT)
如果Minutes的数值是 '0/15' ,表示从0开始每15分钟执行
如果Minutes的数值是 '3/20' ,表示从3开始每20分钟执行,也就是‘3/23/43’
*/