栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

Quartz.NET开源库实现作业定时调度——简单示例

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Quartz.NET开源库实现作业定时调度——简单示例

零、效果图

Quartz.NET开源库实现作业定时调度——常用示例_xiaochenXIHUA的博客-CSDN博客

Quartz.NET作业定时任务调度简单示例工程下载

一、Quartz.NET简介 1.1、.NET Framework自带的Timer定时器介绍

    很多的软件项目中都会使用到定时任务、定时轮询数据库同步,定时邮件通知等功能。.NET Framework具有“内置”定时器功能,通过System.Timers.Timer类实现。

自带定时器的缺点:

①在使用Timer类需要面对的问题:计时器没有持久化机制;

②计时器具有不灵活的计划(仅能设置开始时间和重复间隔,没有基于日期,时间等);

③计时器不使用线程池(每个定时器一个线程);计时器没有真正的管理方案 - 你必须编写自己的机制,以便能够记住,组织和检索任务的名称等。

1.2、Quartz.NET介绍

    Quartz.NET是一个强大、开源、轻量的作业调度框架,可以与任何其他软件系统集成或一起使用。作业调度程序是一个系统,负责在执行预处理程序时执行(或通知)其他软件组件 - 确定(调度)时间到达。Quartz是非常灵活的,并且包含多个使用范例,可以单独使用或一起使用,以实现您所需的行为,并使您能够以您的项目看起来最“自然”的方式编写代码。

Quartz.NET优点:

①组件的使用非常轻便,并且需要非常少的设置/配置,如果您的需求相对基础,它实际上可以使用“开箱即用。

②是容错的,并且可以在系统重新启动之间保留(记住)您的预定作业。

③能够用它来为执行一个作业而创建简单的或复杂的作业调度。它有很多特征,如:数据库支持,集群,插件,支持cron-like表达式等等。非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等。

    Quartz是作为一个小的动态链接库(.dll文件)分发的,它包含所有的核心Quartz功能。 此功能的主要接口(API)是调度程序接口。 它提供简单的操作,如调度/非调度作业,启动/停止/暂停调度程序。如果你想安排你自己的软件组件执行,他们必须实现简单的Job接口,它包含方法execute()。 如果希望在计划的触发时间到达时通知组件,则组件应实现TriggerListener或JobListener接口。主要的Quartz'进程'可以在您自己的应用程序或独立应用程序(使用远程接口)中启动和运行。

1.3、Quarzt.NET的官方地址

官网:http://www.quartz-scheduler.net/

源码:https://github.com/quartznet/quartznet

示例:Quartz.NET Quick Start Guide | Quartz.NET (quartz-scheduler.net)

Quartz.NET是 OpenSymphony 的 Quartz API 的.NET移植,用C#改写,可用于winform和Web应用中。它灵活而不复杂,你能够用它来为执行一个作业而创建简单的或复杂的作业调度。Quartz.NET 3.0 已经开始支持 .NET Core/.NET Standard 2.0。

    Job 为作业的接口,JobDetail 用来描述 Job 的实现类及其它相关的静态信息;Trigger 作为作业的定时管理工具。

    一个 Trigger 只能对应一个作业实例,而一个作业实例可对应多个 Trigger ;

    Scheduler 做为定时任务容器,它包含了所有触发器和作业,每个 Scheduler 都存有 JobDetail 和 Trigger的注册,一个 Scheduler 中可以注册多个 JobDetail 和多个 Trigger 。 

二、实现步骤 2.1、安装Quartz.NET包

2.2、创建一个简单的定时任务示例

这里实现一个定时执行方法输出执行时间的示例

1、编写需要定时执行的方法,必须继承【IJob】


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

namespace TestQuartz.FixedTimeTask
{
    class TimeJob : IJob
    {
        /// 
        /// 作业调度定时执行的方法
        /// 
        /// 
        /// 
        public async Task Execute(IJobExecutionContext context)
        {
            string str = $"{this.GetType().Name} 方法执行,执行时间是:{DateTime.Now} ID:{context.FireInstanceId}" +Environment.NewLine;
            await Console.Out.WriteLineAsync(str);
        }

    }//Class_end

}

2、要定时执行这个方法,你需要先用【IJobDetail】接口绑定该方法,然后再使用【ITrriger】接口监听,接着使用【StdSchedulerFactory】调度工厂实例化【IScheduler】调度器接口启动;

//1、使用IJobDetail 接口绑定需要定时执行的方法【TimeJob】
IJobDetail job = JobBuilder.Create()
	.WithIdentity("job1", "group1")
	.Build();

// 2、使用ITrriger监听器每10秒重复监听
ITrigger trigger = TriggerBuilder.Create()
	.WithIdentity("trigger1", "group1")
	.StartNow()
	.WithSimpleSchedule(x => x
		.WithIntervalInSeconds(10)
		.RepeatForever())
	.Build();

// 3、通知调度器用定义好的监听器执行该绑定的方法
await scheduler.ScheduleJob(job, trigger);

// 注意:你也可以让调度器使用多个监听器监听同一个方法
// await scheduler.ScheduleJob(job, new List() { trigger1, trigger2 }, replace: true);

3、确定任务执行的时间间隔

//任务执行的时间间隔(可自定义,比如这里的是10秒)
await Task.Delay(TimeSpan.FromSeconds(10));

4、还可以添加日志记录,不过当没有任何日志接口对接时,该日志则不进行记录。

//日志类需要继承ILogProvider接口
private class ConsoleLogProvider : ILogProvider
{
    public Logger GetLogger(string name)
    {
        return (level, func, exception, parameters) =>
        {
            if (level >= LogLevel.Info && func != null)
            {
                Console.WriteLine("[" + DateTime.Now.ToLongTimeString() + "] [" + level + "] " + func(), parameters);
            }
            return true;
        };
    }

    public IDisposable OpenNestedContext(string message)
    {
        throw new NotImplementedException();
    }

    public IDisposable OpenMappedContext(string key, object value, bool destructure = false)
    {
        throw new NotImplementedException();
    }
}

//调用方法
LogProvider.SetCurrentLogProvider(new ConsoleLogProvider());
2.3、完整的调用示例
using System;
using System.Threading.Tasks;

using Quartz;
using Quartz.Impl;
using Quartz.Logging;

namespace QuartzSampleApp
{
    public class Program
    {
        private static async Task Main(string[] args)
        {
            LogProvider.SetCurrentLogProvider(new ConsoleLogProvider());

            // Grab the Scheduler instance from the Factory
            StdSchedulerFactory factory = new StdSchedulerFactory();
            IScheduler scheduler = await factory.GetScheduler();

            // and start it off
            await scheduler.Start();

            // define the job and tie it to our HelloJob class
            IJobDetail job = JobBuilder.Create()
                .WithIdentity("job1", "group1")
                .Build();

            // Trigger the job to run now, and then repeat every 10 seconds
            ITrigger trigger = TriggerBuilder.Create()
                .WithIdentity("trigger1", "group1")
                .StartNow()
                .WithSimpleSchedule(x => x
                    .WithIntervalInSeconds(10)
                    .RepeatForever())
                .Build();

            // Tell quartz to schedule the job using our trigger
            await scheduler.ScheduleJob(job, trigger);

            // some sleep to show what's happening
            await Task.Delay(TimeSpan.FromSeconds(60));

            // and last shut down the scheduler when you are ready to close your program
            await scheduler.Shutdown();

            Console.WriteLine("Press any key to close the application");
            Console.ReadKey();
        }

        // simple log provider to get something to the console
        private class ConsoleLogProvider : ILogProvider
        {
            public Logger GetLogger(string name)
            {
                return (level, func, exception, parameters) =>
                {
                    if (level >= LogLevel.Info && func != null)
                    {
                        Console.WriteLine("[" + DateTime.Now.ToLongTimeString() + "] [" + level + "] " + func(), parameters);
                    }
                    return true;
                };
            }

            public IDisposable OpenNestedContext(string message)
            {
                throw new NotImplementedException();
            }

            public IDisposable OpenMappedContext(string key, object value, bool destructure = false)
            {
                throw new NotImplementedException();
            }
        }
    }

    public class TimeJob: IJob
    {
        public async Task Execute(IJobExecutionContext context)
        {
           string str = $"{this.GetType().Name} 方法执行,执行时间是:{DateTime.Now} ID:{context.FireInstanceId}" +Environment.NewLine;
            await Console.Out.WriteLineAsync(str);
        }
    }
}
三、封装好了一个简易的单个任务调度器 3.1、单个定时任务调度器的核心

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

namespace FixedTimeTask
{
    class SingleTaskScheduler
    {
        #region   基础参数
        //调度工厂
        private static StdSchedulerFactory _factory;
        //调度器
        private static IScheduler _scheduler;


        //详细任务
        private IJobDetail _job;
        //触发器
        private ITrigger _trigger;

        //触发的时间间隔
        private int _trrigerInterval = 5;

        //任务执行的时间间隔
        private int _taskRunInterval = 20;

        //执行次数
        private uint _runNumber = 0;

        #endregion


        /// 
        /// 构造函数
        /// 
        /// 任务执行的时间间隔
        /// 触发器的时间间隔
        public SingleTaskScheduler(int taskRunInterval,int trrigerInterval)
        {
            _taskRunInterval = taskRunInterval;
            _trrigerInterval = trrigerInterval;
        }



        #region   公有方法

        /// 
        /// 启动定时方法
        /// 
        /// 
        public async Task StartFiexedTimeMethod()where T:IJob
        {
            Console.WriteLine("开始调用定时任务!!!");
            //创建日志
            LogProvider.SetCurrentLogProvider(new ConsoleLogProvider());

            //从调度工厂获取调度器实例
            _factory = new StdSchedulerFactory();
            _scheduler = await _factory.GetScheduler();

            //启动实例
            await _scheduler.Start();

            //绑定定时执行方法
            BindFiexedTimeMethod();

            //创建定时执行的触发器
            CreateFiexedTimeTrigger(_trrigerInterval);

            //告诉quartz用我们的触发器安排任务
            await _scheduler.ScheduleJob(_job,_trigger);

            //任务执行的时间间隔
            await Task.Delay(TimeSpan.FromSeconds(_taskRunInterval));

            Console.WriteLine("------------执行完成一轮定时任务----------");
        }

        /// 
        /// 关闭定时方法
        /// 
        /// 返回关闭结果
        public bool CloseFiexedTimeMethod()
        {
            Task task=_scheduler?.Shutdown();

            return task.IsCompletedSuccessfully;
        }

        #endregion



        #region   私有方法
        /// 
        /// 绑定定时方法
        /// 
        private void BindFiexedTimeMethod()where T:IJob
        {
             _job = JobBuilder.Create()
                //.WithIdentity("时间任务1", "组1")
                .Build();


        }

        /// 
        /// 创建定时执行触发器
        /// 
        /// 
        private void CreateFiexedTimeTrigger(int seconds)
        {
            if (seconds < 0) return;

            _trigger = TriggerBuilder.Create()
             //.WithIdentity("时间任务触发器1", "组1")
                .StartNow()
                .WithSimpleSchedule(x => x
                .WithIntervalInSeconds(seconds)
                .RepeatForever())
                .Build();
        }


        #endregion 

    }//Class_end

}
3.2、单定时任务调度器使用方法
//1-引用命名空间
using FixedTimeTask;

//2-实例化单定时任务调度器(可以自由定义:任务执行的时间间隔、与触发器执行的时间间隔)
SingleTaskScheduler taskScheduler = new SingleTaskScheduler(10,5);

//3-启动定时方法

await taskScheduler.StartFiexedTimeMethod();

//4-最后可以关闭定时方法
bool success = taskScheduler.CloseFiexedTimeMethod();
四、其他使用Quartz.NET的参考

详解免费开源的DotNet任务调度组件Quartz.NET(.NET组件介绍之五)_实用技巧_脚本之家 (jb51.net)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/979895.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号