Quartz实现.Net Core项目定时任务

准备工作

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’
*/

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值