Quartz.net的最佳实践

这篇具有很好参考价值的文章主要介绍了Quartz.net的最佳实践。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Quartz.NET 官网

Quartz.net是什么

Quartz.NET 是一个功能齐全的开源作业调度系统,他的前身来源于java的Quartz.

Quartz.net安装和使用

基于visual studio引用安装,其他IDE类似,或者下载DLL手动引用也是可以的;运行环境基于.net core,源.net程序类似
Quartz.net的最佳实践
 

Quartz.net的架构和关键属性以及方法

三个主要的概念

  • scheduler 作业调度,作业计划在给定触发器发生时运行,实际就是领导
  • job 作业,实现简单 IJob 接口的任何 .NET 类,实际就是干活的员工
  • trigger 侦听器,负责捕获调度事件以监视或控制作业,实际就是监工

可以这样理解:

监工发现员工偷懒了,报告给领导,领导知道后,给员工派了很多活,导致了员工天天996. 大概是这么个关系;
同时呢,一个员工可以被多个监工监理,同理一个监工也可以监理多个员工,他们是多对多的关系;多个员工也可以共属于一个领导,当然也可以一个领导只有一个员工,他们直接也是多对多的关系

Quartz.net的一些关键属性

类型
 
ISchedulerFactory
SchedulerBuilder的工厂类
IScheduler
用于与调度程序交互的主要 API
SchedulerBuilder
用于定义/构建调度程序实例,需要 Quartz 3.1 或更高版本
IJobFactory
JobBuilder的工厂类
IJob
由您希望由调度程序执行的组件实现的接口
IJobDetail
用于定义作业的实例
JobBuilder
用于定义/构建 JobDetail 实例,这些实例定义作业的实例
TriggerBuilder
用于定义/构建触发器实例
ITrigger
定义执行给定作业的计划的一个组件,作业可以有多个关联的触发器
ListenerManager
侦听器事件,例如:执行job工作之前,之后触发等等,同时也可用于触发器侦听

IServiceCollectionQuartzConfigurator 参数

Scheduler Name
调度作业的名称
Scheduler Id
SchedulerId
Max Batch Size
同时执行job的最大数量
InterruptJobsOnShutdown
 
InterruptJobsOnShutdownWithWait
 
BatchTriggerAcquisitionFireAheadTimeWindow
 

在通用host或者webhost中的最佳实践

通用host或者webhost代码是一样的

执行流程

  1. 在通用主机服务中注入服务AddQuartz,AddQuartzHostedService
  2. 在AddQuartz中配置调度作业的基本属性(SchedulerId等等)和调度器以及作业(ScheduleJob,AddJob,AddTrigger);可以在这个地方写入所有的调度作业,也可以写入一个initjob作业,在主机完全启动5秒后执行相应的业务(可规避掉某些依赖服务未启动的问题)
  3. 在initjob中,初始化其他定时任务。官网介绍job只能有一个无参的构造函数,但我亲测可以注入(笑脸)
  4. 关于job和reigger的具体参数,可查看官网
以下代码和执行结果,其中执行顺序一目了然

代码

   static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");

            LogProvider.SetCurrentLogProvider(new ConsoleLogProvider());
            //通用主机配置
            var build = Host.CreateDefaultBuilder(args)
                .ConfigureServices((host, services) =>
                {
                    Console.WriteLine("--------1");
                    
                    //调度作业的唯一id的唯一标识,用于集群搭建cluster
                    q.SchedulerId = "SchedulerId_01";
                    //配置Quartz服务
                    services.AddQuartz(q =>
                    {
                        Console.WriteLine("--------2");
                        //依赖注入,ISchedulerFactory,Ijob等等
                        q.UseMicrosoftDependencyInjectionJobFactory();

                        //方法一和方法二使用不同方法的写法,本质基本是一样的
                        //方法一
                        q.ScheduleJob<InitJob>(
                            trigger =>
                            {
                                Console.WriteLine("--------33");
                                //WithIdentity 绑定触发器或者job的唯一属性和组
                                //TriggerKey,JobKey 都是代表唯一个属性和组
                                trigger.WithIdentity(new TriggerKey("trigger1", "triggergroup1"))
                                       .WithSimpleSchedule(x => x.WithIntervalInSeconds(5))
                                       // .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(5)))
                                       //  .WithDailyTimeIntervalSchedule(x => x.WithInterval(10, IntervalUnit.Second))
                                       .WithDescription("init 描述");
                            },
                            jobConfigure =>
                            {
                                Console.WriteLine("--------44");
                                jobConfigure.WithIdentity(new JobKey("Init1", "jobgroup1"));
                            }
                        );

                        //方法二
                        //q.AddJob<InitJob>(opts =>
                        //{
                        //    Console.WriteLine("--------3");
                        //    opts.WithIdentity(new JobKey("Init1", "jobgroup1"));

                        //});

                        //q.AddTrigger(opts =>
                        //{
                        //    Console.WriteLine("--------4");
                        //    //将job添加至触发器中
                        //    opts.ForJob(new JobKey("Init1", "jobgroup1"))
                        //    .WithIdentity("trigger1", "triggergroup1")
                        //    .WithSimpleSchedule(x =>
                        //    {
                        //        Console.WriteLine("--------6");
                        //        x.WithIntervalInSeconds(5);
                        //        //.RepeatForever();
                        //        //.WithRepeatCount(5);
                        //    });

                        //});

                    });
                    services.AddQuartzHostedService(options =>
                    {    
                        options.WaitForJobsToComplete = true;
                    });

                }).Build();

            //var schedulerFactory =  build.Services.GetService<ISchedulerFactory>();
            //var scheduler = schedulerFactory.GetScheduler();
            build.Run();
            Console.WriteLine("--------7");
        }
    }


    public class SampleJob : IJob
    {
        public SampleJob(ISchedulerFactory schedulerFactory, IJobFactory jobFactory)
        {
            Console.WriteLine("--------8");
        }
        public async Task Execute(IJobExecutionContext context)
        {
            Console.WriteLine("--------9");
            context.JobDetail.JobDataMap.GetString("我是sample的job数据key");
            Console.WriteLine($"我是sample的job数据key: {context.JobDetail.JobDataMap.GetString("我是sample的job数据key")}");
            Console.WriteLine($"我是sample的Trigger数据key: {context.MergedJobDataMap.GetString("我是sample的Trigger数据key")}");

        }
    }
    public class InitJob : IJob
    {
        public ISchedulerFactory _schedulerFactory;
        public IJobFactory _jobFactory;
        public InitJob(ISchedulerFactory schedulerFactory, IJobFactory jobFactory)
        {
            Console.WriteLine("--------12");
            _schedulerFactory = schedulerFactory;
            _jobFactory = jobFactory;
        }
        public async Task Execute(IJobExecutionContext context)
        {
            Console.WriteLine("--------13");
            Console.WriteLine("InitJob Execute " + Random.Shared.Next(0, 100));
            
            //创建job
            IJobDetail job = JobBuilder.Create<SampleJob>()
                                //写入参数
                                .UsingJobData("我是sample的job数据key", "我是sample的job数据value")
                                .WithIdentity("sample1", "jobgroup1").Build();
            //创建触发器
            ITrigger trigger = TriggerBuilder.Create()
                                   .UsingJobData("我是sample的Trigger数据key", "我是sample的Trigger数据value")
                                   .WithIdentity("trigger_sample1", "triggergroup1")
                                   .WithDescription("我是描述")
                                   //通过corn符号来创建触发器
                                   //.WithCronSchedule(taskOptions.CronExpression)
                                   .WithSimpleSchedule(x =>
                                       x.WithIntervalInSeconds(5) //5秒后执行
                                       .RepeatForever()  //重复
                                    )
                                   .Build();
            //通过工厂获取一个作业调度
            var scheduler = await _schedulerFactory.GetScheduler();
            //绑定一个job的事件侦听器,从执行顺序上看 new JobListen是一个单例类
            scheduler.ListenerManager.AddJobListener(new JobListen(), KeyMatcher<JobKey>.KeyEquals(new JobKey("sample1", "jobgroup1")));
            //将作业和从触发器绑定至作业调度上
            await scheduler.ScheduleJob(job, trigger);
            //启动作业调度
            await scheduler.Start();

            Console.WriteLine("--------14");
        }
    }
    //作业侦听器
    public class JobListen : JobListenerSupport
    {
        public JobListen()
        {
            Console.WriteLine("--------20");
        }
        public override string Name { get { return "JobListen20"; } }
        //调用job之前执行
        public override Task JobToBeExecuted(IJobExecutionContext context, CancellationToken cancellationToken)
        {
            Console.WriteLine("--------21");
            return base.JobToBeExecuted(context, cancellationToken);
        }
    }
    //日志组件
    public 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();
        }
    }

执行结果

Quartz.net的最佳实践

Quartz的增删改查(新增删除添加任务)

 

internal class Program
    {

        static void Main(string[] args)
        {
            var host = Host.CreateDefaultBuilder(args)
                .ConfigureServices(services => {
                    services.AddQuartz(service =>
                    {
                        service.UseMicrosoftDependencyInjectionJobFactory();
                        service.SchedulerId = "SchedulerId";
                    });
                    services.AddQuartzHostedService(service => {
                        service.WaitForJobsToComplete = true;
                    });
                    services.AddHostedService<Worker>();
                })
                .Build();
            host.Run();

        }

    }

    public static class QuartzHelper
    {
        public static void Start<T>(TaskOptions taskOptions, ISchedulerFactory schedulerFactory, IJobFactory jobFactory)
                where T : class, IJob, new()
        {
            Triiger<T>(JobAction.开启, taskOptions, schedulerFactory, jobFactory);
        }

        public static async void Add<T>(TaskOptions taskOptions, ISchedulerFactory schedulerFactory, IJobFactory jobFactory)
            where T:class,IJob,new()
        {
            IJobDetail job = JobBuilder.Create<T>()
               .WithIdentity(new JobKey(taskOptions.TaskName, taskOptions.GroupName)).Build();
            ITrigger trigger = TriggerBuilder.Create()
               .WithIdentity(new TriggerKey(taskOptions.TaskName, taskOptions.GroupName))
               .WithDescription(taskOptions.Describe)
               .WithCronSchedule(taskOptions.CronExpression)
               .Build();

            IScheduler scheduler = null;
            if (string.IsNullOrEmpty(taskOptions.InstanceName) && string.IsNullOrEmpty(taskOptions.InstanceId))
            {
                //从工厂获取调度中心,获取的是一个单例调度中心,对单一的调度中心操作会影响全局的调度,比如:scheduler.stop() 会停止掉所有的调度中心
                //如果需要分别控制,需要创建自定义的调度中心,如下:
                
                //创建自定义的调度中心
                var collection = new System.Collections.Specialized.NameValueCollection();
                collection.Add("quartz.scheduler.instanceName", taskOptions.InstanceName);
                collection.Add("quartz.scheduler.instanceId", taskOptions.InstanceId);
                ISchedulerFactory schedulerFactory2 = new StdSchedulerFactory(collection);
                scheduler = await schedulerFactory2.GetScheduler();
            }
            else
            {
                scheduler = await schedulerFactory.GetScheduler();
            }
            await scheduler.ScheduleJob(job, trigger);
            await scheduler.Start();

        }

        public static async void Triiger<T>(JobAction jobAction, TaskOptions taskOptions, ISchedulerFactory schedulerFactory, IJobFactory jobFactory)
              where T : class, IJob, new()
        { 
            IScheduler scheduler = await schedulerFactory.GetScheduler();
            //获取指定组下所有job
            List<JobKey> jobKeys = scheduler.GetJobKeys(GroupMatcher<JobKey>.GroupEquals(taskOptions.GroupName)).Result.ToList();
            //从该组中获取包含触发器名称的job
            JobKey jobKey = jobKeys.Where(s => scheduler.GetTriggersOfJob(s).Result.Any(x => (x as CronTriggerImpl).Name == taskOptions.TaskName)).FirstOrDefault();
            //获取当前触发器
            var triggers = await scheduler.GetTriggersOfJob(jobKey);
            ITrigger trigger = triggers?.Where(x => (x as CronTriggerImpl).Name == taskOptions.TaskName).FirstOrDefault();

            switch (jobAction)
            {
                case JobAction.删除:
                    await scheduler.PauseTrigger(trigger.Key); //暂停
                    await scheduler.UnscheduleJob(trigger.Key);// 移除触发器
                    await scheduler.DeleteJob(trigger.JobKey); //删除job
                    break;
                case JobAction.更新:
                    //先删除,再添加
                    await scheduler.PauseTrigger(trigger.Key);
                    await scheduler.UnscheduleJob(trigger.Key);// 移除触发器
                    await scheduler.DeleteJob(trigger.JobKey);

                    Add<T>(taskOptions, schedulerFactory, jobFactory);
                    break;
                case JobAction.暂停:
                    await scheduler.PauseTrigger(trigger.Key);
                    break;
                case JobAction.开启:
                    await scheduler.ResumeTrigger(trigger.Key);
                    break;
                case JobAction.立即执行:
                    await scheduler.TriggerJob(jobKey);
                    break;
            }
        }
    }
    public class TaskOptions
    { 
        public string Id { get; set; }
        public string TaskName { get; set; }
        public string GroupName { get; set; }
        public string Describe { get; set; }
        public string CronExpression { get; set; }
        public string InstanceName { get; set; }
        public string InstanceId { get; set; }
    }

    public enum JobAction
    { 
        开启,
        暂停,
        删除,
        更新,
        立即执行
    }

    public class Job : IJob
    {
        public Task Execute(IJobExecutionContext context)
        {
            throw new NotImplementedException();
        }
    }
        public class Worker : IHostedService
    {
        public ISchedulerFactory _schedulerFactory { get; set; }
        public IJobFactory _jobFactory { get; set; }
        public Worker(ISchedulerFactory schedulerFactory, IJobFactory jobFactory)
        {
            _schedulerFactory = schedulerFactory;
            _jobFactory = jobFactory;
        }
        Task IHostedService.StartAsync(CancellationToken cancellationToken)
        {
            QuartzHelper.Add<Job>(new TaskOptions() { CronExpression = "0/10 * * * * ?", GroupName = "GroupName", TaskName = "TaskName" }, _schedulerFactory, _jobFactory);
            return Task.CompletedTask;
        }

        Task IHostedService.StopAsync(CancellationToken cancellationToken)
        {
            throw new NotImplementedException();
        }
    }

 文章来源地址https://www.toymoban.com/news/detail-490449.html

到了这里,关于Quartz.net的最佳实践的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Quartz.Net调度框架简介

    Quartz.Net是一个功能强大的开源任务调度框架,它可以在C#应用程序中实现灵活、可靠的任务调度和定时作业。它的主要作用是允许开发人员按照预定的时间表执行各种任务,例如定期生成报表、发送电子邮件、备份数据等。 在C#中使用Quartz.Net进行配置、开发和部署的步骤如下

    2024年02月09日
    浏览(28)
  • Quartz.NET,强大的开源作业调度框架

    Quartz.NET是一个强大的开源作业调度框架,专为C#和.NET开发而设计。它允许开发人员在应用程序中调度、执行和管理各种类型的作业,例如定时任务、后台作业、周期性作业等。Quartz.NET具有高度可配置性和灵活性,可以满足各种复杂的调度需求。 **作用:** Quartz.NET的作用在于

    2024年02月09日
    浏览(37)
  • Quartz.NET配置文件:简便任务调度,轻松管理

      概述: Quartz.NET是一个强大的任务调度库,支持通过配置文件灵活配置任务和触发器。配置文件中定义了调度器、线程池、作业和触发器的相关信息。默认情况下,Quartz.NET在应用程序根目录查找名为 quartz.config 的配置文件。若配置文件位于其他路径或具有不同名称,可以通

    2024年03月09日
    浏览(37)
  • 基于 Quartz.NET 可视化任务调度平台 QuartzUI

    QuartzUI 是基于 Quartz.NET3.0 的定时任务 Web 可视化管理,Docker 打包开箱即用、内置 SQLite 持久化、语言无关、业务代码零污染、支持 RESTful 风格接口、傻瓜式配置、异常请求邮件通知等。 QuartzUI 从 2022 年到现在没有提交记录,这里的部署使用的是最后一个版本的镜像。Windows D

    2024年04月25日
    浏览(24)
  • ASP.NET Core MVC+Quartz实现定时任务可视化管理页面

    在前一篇文章,我们了解了如何通过.NET6+Quartz开发基于控制台应用程序的定时任务,今天继续在之前的基础上,进一步讲解基于ASP.NET Core MVC+Quartz实现定时任务的可视化管理页面,仅供学习分享使用,如有不足之处,还请指正。 Quartz组件,关于Quartz组件的基本介绍,可参考前

    2024年02月01日
    浏览(37)
  • 微软官网下载Net Framework流程

    1、官网下载链接 https://dotnet.microsoft.com/en-us/download/dotnet-framework/net451 2、选择合适的版本 3、点击下载

    2024年02月16日
    浏览(37)
  • .NET爬取美图官网首页数据实战

    在当今信息化社会,网络数据分析越来越受到重视。而作为开发人员,掌握一门能够抓取网页内容的语言显得尤为重要。在此篇文章中,将分享如何使用 .NET构建网络抓取工具。详细了解如何执行 HTTP 请求来下载要抓取的网页,然后从其 DOM 树中选择 HTML 元素,进行匹配需要的

    2024年02月13日
    浏览(38)
  • .Net4.0 Web.config 配置实践

    目录 关于 Web.config 运行环境 配置实践 请求验证模式兼容旧版本 上传文件限制 Request.Path危险值配置 全站应用UTF-8编码 设置日期格式 每个会话的限制并发请求数 正常运行指定扩展名的文件 Json字符串超出最大长度限制 控件早期版本的呈现方式 C# 操作 Web.config 小结 当通过.N

    2024年04月23日
    浏览(19)
  • 【ASP.NET Web】项目实践—网上宠物店8:制作“商品展示”页面

    网站通过 Products.aspx 页面展示所销售的宠物。 分析商品展示页面的界面: 内容实现,要写在占位符控件中。 分析产品展示页面的功能: Products.aspx 页面使用一个 DataList 控件,以两列的形式展示商品,每个商品包括商品名称、描述、价格、图片等信息。此外,页面显示哪一类

    2024年02月06日
    浏览(68)
  • Json Schema介绍 和 .net 下的实践 - 基于Lateapexearlyspeed.Json.Schema - 基础1 - type关键字和string类型

    本系列旨在介绍Json Schema的常见用法,以及.net实现库Lateapexearlyspeed.Json.Schema的使用 这篇文章将介绍Json Schema中的type,和string类型的常见验证功能。用例基于.net的LateApexEarlySpeed.Json.Schema nuget package。这是新创建的一个 Json Schema在.net下的高性能实现库。 就像其他各种Sch

    2024年02月02日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包