Quartz.Examples

反射-Example批量执行

​ 实现思路:定义一个统一的接口,需要实现的类全部实现该接口;通过反射获取实现该接口的实例并触发其中的方法。

  • 定义统一的接口

    // 所有要实现类都要有Run方法
    public interface IExample
    {
    Task Run();
    }
  • 利用反射实例化

    //反射的方式获得程序配置信息
    Assembly asm = typeof(Program).GetTypeInfo().Assembly;
    // 获得该程序的所有类型
    Type[] types = asm.GetTypes();
    List<Type> typeList = new List<Type>();
    foreach (Type t in types)
    {
    // 判断是否继承的IExample接口
    if (new List<Type>(t.GetInterfaces()).Contains(typeof(IExample)))
    {
    typeList.Add(t);
    }
    }
    // 实例化第一个接口实现类
    IExample example = ObjectUtils.InstantiateType<IExample>(typeList[0]);
    // 执行接口中的Run方法
    await example.Run().ConfigureAwait(false);
DateTimeOffset

​ UTC时间为协调世界时 (UTC) 的日期和时间,

  1. 不建议使用DateTime,因为DateTime一般默认为本地时间+时区,不会有时间偏移的概念,不同时区的时间相等但是不是同一时间。

  2. DateTimeOffset.Now和DateTimeOffset.UtcNow

    • 相同点 获得的实际值一样(ToUnixTimeSecondes)

      // Now秒:   1675238417
      // UtcNow秒:1675238417
      Console.WriteLine($"Now秒: {DateTimeOffset.Now.ToUnixTimeSeconds()}");
      Console.WriteLine($"UtcNow秒:{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}");
    • 不同点 展示不一样,Now为本地时区时间,UtcNow为0时区的时间。

      // Now时间   :2023/2/1 16:00:17 +08:00
      // UtcNow时间:2023/2/1 8:00:17 +00:00
      Console.WriteLine($"Now时间 :{DateTimeOffset.Now}");
      Console.WriteLine($"UtcNow时间:{DateTimeOffset.UtcNow}");
  3. DateTime与DateTimeOffset 转换

    //DateTimeOffset 转 DateTime
    // 时区丢失,即dateTime.Kind为UnSpecified
    DateTime dateTime=dateTimeOffset.DateTime;
    // 时区为Local
    DateTime dateTime=DateTime.SpecifyKind(dateTimeOffset,DateTimeKind.Local);
    // 本地时区换算为本地时间,且dateTime.Kind为Local
    DateTime dateTime=dateTimeOffset.LocalTime;
    // 本地时区换算为utc时间(0时区),且dateTime.Kind为Utc
    DateTime dateTime=dateTimeOffset.UtcDateTime;
    // DateTime转DateTimeOffset
    // 直接转换为本地时间+时区
    DateTimeOffset dateTimeOffset = new DateTimeOffset(dateTime);
    // Utc时间 dateTimeOffset与dateTime时区会不同,造成展示的时间不同
    DateTimeOffset dateTimeOffset = new DateTimeOffset(dateTime, TimeZoneInfo.Local.GetUtcOffset(dateTime));
    // 设置时间+查找时区相对应的时间 dateTimeOffset与dateTime会相同
    DateTimeOffset dateTimeOffset = new DateTimeOffset(dateTime, TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time").GetUtcOffset(dateTime))
  4. 注意:Quartz.NET使用了DateTimeOffset进行的时间操作

TimeSpan

时间间隔,例如

TimeSpan.FromSeconds(65) 返回65秒的TimeSpan实例

TimeSpan.Zero 间隔是0秒

new TimeSpan(2, 14, 18) 间隔2小时14分钟18秒

DateTime减法

DateTime departure = new DateTime(2010, 6, 12, 18, 32, 0);
DateTime arrival = new DateTime(2010, 6, 13, 22, 47, 0);
TimeSpan travelTime = arrival - departure;
// 结果:6/13/2010 10:47:00 PM - 6/12/2010 6:32:00 PM = 1.04:15:00
DateBuilder

Quzrtz.NET自带设置类,方便设置和操作DateTimeOffset类。

// date时间后的一个小时,例如date为8:44:59,调用方法后获得时间为 9:00:00
// 如果参数为null,则为当前时间
static DateTimeOffset EvenHourDate(DateTimeOffset? date)
// 同DateBuilder.EvenHourDate(null);
static DateTimeOffset EvenHourDateAfterNow()
// data时间前的一个小时,例如date为8:44:59,调用方法后获得时间为 8:00:00
static DateTimeOffset EvenHourDateBefore(DateTimeOffset? date)
// 同EvenHourDate,不过由小时变为了分钟; EvenMinuteDateBefore和EvenMinuteDateAfterNow同上
static DateTimeOffset EvenMinuteDate(DateTimeOffset? date)
// EvenSecondDate EvenSecondDateBefore EvenSecondDateAfterNow同上 /*
当前时间以IntervalUnit为单位增加interval的时间
IntervalUnit为枚举类
Millisecond, 毫秒
Second, 秒
Minute, 分
Hour, 小时
Day, 天
Week, 周
Month, 月
Year 年
例如:DateBuilder.FutureDate(1, IntervalUnit.Hour); 当前时间增加一小时后的DateTimeOffset实例
*/
static DateTimeOffset FutureDate(int interval, IntervalUnit unit)
// 创建一个当前时间的DateBuilder实例,可通过Build()方法获得DateTimeOffset
static DateBuilder NewDate
/*
TimeZoneInfo 时区,根据时区不同获取不同时区的当前时间
*/
static DateBuilder NewDateInTimeZone(TimeZoneInfo tz)
// 获得下一分/秒的时间
static DateTimeOffset NextGivenMinuteDate(DateTimeOffset? date, int minuteBase)
static DateTimeOffset NextGivenSecondDate(DateTimeOffset? date, int secondBase)
// 当前时间加上hour小时,minute分钟,second秒
static DateTimeOffset TodayAt(int hour, int minute, int second)
// 当前时间加上1天,hour小时,minute分钟,second秒
static DateTimeOffset TomorrowAt(int hour, int minute, int second)
各Demo说明
  1. 01_SimpleJobScheduler

    最简单的调度程序,任务是打印当前时间

  2. 02_SchedulingCapabilitiesUsingSimpleTriggers

    简单的触发器实例-重复执行,定时执行等

    • TriggerBuilder.Create()创建ISimpleTrigger的实例
    • .WithSimpleSchedule(x => x.WithIntervalInSeconds(10).WithRepeatCount(10)) 每隔10s循环10次,共11次
    • sched.RescheduleJob(trigger.Key, trigger) 重启触发器trigger为触发器实例
    • SchedulerMetaData metaData = await sched.GetMetaData(); 获取调度任务数据
  3. 03_SchedulingCapabilitiesUsingCronTriggers

    cron的触发器实例

    具体cron触发可通过查看cron在线生成来确定触发周期

  4. 04_JobParametersAndJobsStateMaintenance

    JobDataMap添加数据,IJob实例中获取并修改的实例

  5. 05_SchedulingJobsSettingMisfireInstructions

    JobDataMap实例(同上)和 一个单元测试

    • UsingJobData(StatefulDumbJob.ExecutionDelay, 10000L) 在IJobDetail实例时调用该方法赋值
    • WithMisfireHandlingInstructionNowWithExistingCount() 设置了运行失败后的计数---通过await Task.Delay(10000L)实现的
  6. 06_JobExecutionExceptions

    JobExecutionException的例子

    • 作业重新开始执行
    // 将Exception异常转换为JobExecutionException异常
    JobExecutionException e2 = new JobExecutionException(e);
    // 如果报错不可以修复,可以让该触发器结束执行,避免一直报错
    e2.UnscheduleAllTriggers = true;
    // 如果报错可以修复,可以在报错修复后重新执行
    e2.RefireImmediately = true;
    throw e2;
  7. 07_InterrupInProgressJobs

    调度程序中每七秒中断一次作业,共中断50次

    // 调度程序中中断作业,job.Key 作业的唯一key
    await sched.Interrupt(job.Key);
    // IJob实例中判断中断代码片段
    // 当该值为true时,要求中断
    context.CancellationToken.IsCancellationRequested
  8. 08_ExcludeTimePeriodsUsingCalendars

    通过判断ModifiedByCalendar,来排除不执行的时间

    // 创建日历
    AnnualCalendar holidays = new AnnualCalendar();
    // 生成一个排除的时间
    DateTime fourthOfJuly = new DateTime(DateTime.UtcNow.Year, 7, 4);
    // 在日历中添加该时间
    holidays.SetDayExcluded(fourthOfJuly, true);
    // 将日历添加到调度程序中,,第一个参数为实例名称,第三个参数为替换之前的日历,第四个参数为更新触发器
    await sched.AddCalendar("holidays", holidays, false, false);
    // 引用实例名称
    ISimpleTrigger的实例.ModifiedByCalendar("holidays")
  9. 09_TriggeringAJobUsingJobListeners

    在作业中启用了监听,并在监听中创建了新的作业

    • 创建监听并添加到调度程序中

      // 实例化监听
      IJobListener listener = new SimpleJob1Listener();
      // 创建匹配器,并设置作业的key
      IMatcher<JobKey> matcher = KeyMatcher<JobKey>.KeyEquals(job.Key);
      // 将监听和匹配器关联
      sched.ListenerManager.AddJobListener(listener, matcher);
    • SimpleJob1Listener

      public class SimpleJob1Listener : IJobListener
      {
      public virtual string Name => "job1_to_job2";
      // 作业将被执行
      public virtual Task JobToBeExecuted(IJobExecutionContext inContext, CancellationToken canncellationToken)
      {
      return Task.CompletedTask;
      }
      // 作业完成执行
      public virtual Task JobExecutionVetoed(IJobExecutionContext inContext,CancellationToken canncellationToken)
      {
      return Task.CompletedTask;
      }
      // 作业执行完成
      public virtual async Task JobWasExecuted(IJobExecutionContext inContext,JobExecutionException? inException,CancellationToken canncellationToken = default)
      {
      //在监听器中创建作业和触发器
      IJobDetail job2 = JobBuilder.Create<SimpleJob2>()
      .WithIdentity("job2")
      .Build(); ITrigger trigger = TriggerBuilder.Create()
      .WithIdentity("job2Trigger")
      .StartNow()
      .Build(); try
      {
      // 将触发器和作业添加到调度程序中
      await inContext.Scheduler.ScheduleJob(job2, trigger, canncellationToken);
      }
      catch (SchedulerException e)
      {
      Console.Error.WriteLine("Unable to schedule job2!");
      Console.Error.WriteLine(e.StackTrace);
      }
      }
      }
  10. 10_RunningJobsByPlugInXmlConfiguration

    通过xml配置任务和触发器,xml参见:quartz_jobs.xml

    • MergedJobDataMap

      if (context.MergedJobDataMap.Count > 0)
      {
      ICollection<string> keys = context.MergedJobDataMap.Keys;
      foreach (string key in keys)
      {
      var val = context.MergedJobDataMap.GetString(key);
      Console.WriteLine(" - jobDataMap entry: {0} = {1}", key, val);
      }
      }
  11. 11_RunningLargeNumberOfJobs

    500个任务间隔100ms秒执行,可以查看任务执行效率和资源信息

  12. 12_RemoteClientServerJobScheduling

    代码被注释,官网不建议使用

  13. 13_ClusteringJobsExecution

    集群作业(感觉就是多个调度服务使用同一个数据库的例子)

    • 使用数据库存储

      IScheduler sched = await SchedulerBuilder.Create()
      .WithId("instance_one")
      .WithName("TestScheduler")
      // 线程池
      .UseDefaultThreadPool(x => x.MaxConcurrency = 5)
      //失效后暂停60s
      .WithMisfireThreshold(TimeSpan.FromSeconds(60))
      .UsePersistentStore(x =>
      {
      x.UseProperties = true;
      x.UseClustering();
      // 连接字符串
      x.UseSqlServer(TestConstants.SqlServerConnectionString);
      x.UseJsonSerializer();
      })
      .BuildScheduler();
  14. 14_RunJobsByPriorityWithTriggersPriority

    触发器优先级的例子,默认是5,在相同时间运行时不同级别同时运行时,级别越高越先执行

    ITrigger实例.WithPriority(10)

  15. 15_ConfigureJobSchedulingByUsingXmlConfigurations

    使用xml进行调度器的配置

    var sched = await SchedulerBuilder.Create()
    .WithName("XmlConfiguredInstance")
    .UseDefaultThreadPool(maxConcurrency: 5)
    // 作业和触发器都通过xml进行配置
    .UseXmlSchedulingConfiguration(x =>
    {
    // xml文件
    x.Files = new[] { "~/quartz_jobs.xml" };
    // FailOnFileNotFound默认为true
    x.FailOnFileNotFound = true;
    // FailOnSchedulingError 默认为false
    x.FailOnSchedulingError = true;
    })
    .BuildScheduler();
  16. 16_RunningAsynchronousJobs

    由于作业没执行完毕触发器会再次运行作业,因此相同的作业会异步执行

Quartz.Net源码Example之Quartz.Examples的更多相关文章

  1. Pytorch学习之源码理解:pytorch/examples/mnists

    Pytorch学习之源码理解:pytorch/examples/mnists from __future__ import print_function import argparse import ...

  2. cache2go源码最后一讲 - examples

    先看一下我们讲到哪里了: cache2go的源码前面我们已经讲完了cacheitem和cachetable的实现,今天cahce和examples会一起讲完~ 1.cache.go源码 ​      ...

  3. java ssm 后台框架平台 项目源码 websocket IM quartz springmvc

    A代码编辑器,在线模版编辑,仿开发工具编辑器,pdf在线预览,文件转换编码B 集成代码生成器 [正反双向](单表.主表.明细表.树形表,快速开发利器)+快速表单构建器freemaker模版技术 ,0个 ...

  4. quartz(7)-源码分析

    定时器启动 上图通过spring加载quartz <bean id="scheduler" class="org.springframework.schedulin ...

  5. Quartz.Net系列(三):解读Quartz.Net源码领略设计模式在其中的应用

    1.Builder(建造者)模式 JobBuilder  DateBuilder  其他的Builder(TriggerBuilder.SchedulerBuilder等) 2.抽象工厂模式 ISch ...

  6. quartz集群调度机制调研及源码分析---转载

    quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 quratz是目前最为成熟,使用最广泛的j ...

  7. 定时组件quartz系列<三>quartz调度机制调研及源码分析

    quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 quratz是目前最为成熟,使用最广泛的j ...

  8. anki_vector SDK源码解析(教程)

    一:最近anki vector robot开放了Python SDK,我听到的第一时间就赶快上网查了查,先抛几个官网重要链接吧: Python编程API手册及环境搭建等: https://sdk-re ...

  9. quartz.net任务调度:源码及使用文档

    目录: 1.quartz.net任务调度:源码及使用文档 2.quartz.net插件类库封装 前言 前段时间把自己封装quartz.net 类库的过程总结到博客园,有网友想要看一下源码,所以就把源码 ...

  10. quartz.net插件类库封装(含源码)

    1.前言 目录: 1.quartz.net任务调度:源码及使用文档 2.quartz.net插件类库封装 最近项目需要做一写任务作业调度的工作,最终选择了quartz.net这个插件,它提供了巨大的灵 ...

随机推荐

  1. CSS 动画一站式指南

    CSS 动画一站式指南 目录 CSS 动画一站式指南 1. CSS 动画 1.1 变换 1.1.1 变换属性介绍 1.1.2 变换动画实践 1.2 过渡 1.2.1 过渡属性介绍 1.2.2 过渡动画 ...

  2. Python基础之模块:7、项目开发流程和项目需求分析及软件开发目录

    一.项目开发流程 1.项目需求分析 明确项目具体功能: 明确到底要写什么东西,实现什么功能,在这个阶段的具体要询问项目经理和客户的需求 参与人员: 产品经理.架构师.开发经理 技术人员主要职责: 引导 ...

  3. SQLSever数据库基本操作

    一.SQLSever数据库基本操作 1.创建数据库 use master if exists(select * from sysdatabases where name='SMDB') drop da ...

  4. Linux内存泄露案例分析和内存管理分享

    作者:李遵举 一.问题 近期我们运维同事接到线上LB(负载均衡)服务内存报警,运维同事反馈说LB集群有部分机器的内存使用率超过80%,有的甚至超过90%,而且内存使用率还再不停的增长.接到内存报警的消 ...

  5. CodeQL(1)

    前言 开始学习使用CodeQL,做一些笔记,可供参考的资料还是比较少的,一个是官方文档,但是Google翻译过来,总觉得怪怪的,另一个就是别人的一个资源整合,其中可供参考的也不是很多,大多也是官方文档 ...

  6. bugku web基础$_POST

    这道题也是让what=flag就行了 直接试试通过max hackbar来进行post传入 得到flag

  7. 第2-4-10章 规则引擎Drools实战(3)-保险产品准入规则

    目录 9.3 保险产品准入规则 9.3.1 决策表 9.3.2 规则介绍 9.3.3 实现步骤 9.3 保险产品准入规则 全套代码及资料全部完整提供,点此处下载 9.3.1 决策表 前面我们编写的规则 ...

  8. 【SQL进阶】【REPLACE/TIMESTAMPDIFF/TRUNCATE】Day01:增删改操作

    一.插入记录 1.插入多条记录 自己的答案: INSERT INTO exam_record(uid, exam_id, start_time, submit_time, score) VALUES ...

  9. 【Java SE进阶】Day03 数据结构、List、Set、Collections

    一.数据结构 1.红黑树 根黑子黑红子黑 接近平衡树(左右孩子数量相同),查询叶子快慢次数不超过2倍 二.List 1.概述 元素有序 线性存储 带有索引 可以重复 2.常用方法 增:add(I,E) ...

  10. 【每日一题】【栈】2022年2月2日-NC40 两个链表生成相加链表

    描述 假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数. 给定两个这种链表,请生成代表两个整数相加值的结果链表. 答案:栈 import java.util.*; /* ...