有关Quartz.NET,与一线码农大佬对个线?

简介: 跟[一线码农大佬]翻译的某技术文对个线

最近看到一线码农大佬翻译的《如何在 ASP.NET Core 中使用 Quartz.NET 执行任务调度


行文思路:


  1. 安装Quartz.NET


  1. Quartz.NET 中的Job,triggers 和 Schedulers


  1. 创建 Scheduler


  1. 开启和停止 scheduler


  1. 创建 job 工厂


  1. 创建 JobMetadata 存储你的 job 元数据


不可否认,一线大佬的翻译文还是相当精准的, 但个人认为这篇文章的底稿有点硬输出,并没有以一个流畅、直观的编码思路来讲述[如何在ASP.NET Core中使用Quartz.NET 执行定时任务]。


尤其是下面这段:


7f38d8d6ff49b753816dd0503ee0199c.png


想起我之前也写了《ASP.NET Core+Quartz.Net实现web定时任务》, 文章以一个简单的定时任务讲述了Quartz.NET在ASP.NET Core中的应用思路,遇河架桥,遇山开路。

这里我要解释一下上图中:为什么要自定义一个Job工厂?

先看下官方JobFactory的作用:


ac37c2b3ab53cb45a0897fbf2ff0a68e.png


大意是说:


如果某触发器被触发,该触发器关联的Job将被调度器上配置的JobFactory初始化;

Quartz.NET默认的SimpleJobFactory工厂类,是利用反射+无参构造函数构造出Job实例。


翻源码:


//----------------选自Quartz.Simpl.SimpleJobFactory类-------------
using System;
using Quartz.Logging;
using Quartz.Spi;
using Quartz.Util;
namespace Quartz.Simpl
{
    /// <summary> 
    /// The default JobFactory used by Quartz - simply calls 
    /// <see cref="ObjectUtils.InstantiateType{T}" /> on the job class.
    /// </summary>
    /// <seealso cref="IJobFactory" />
    /// <seealso cref="PropertySettingJobFactory" />
    /// <author>James House</author>
    /// <author>Marko Lahma (.NET)</author>
    public class SimpleJobFactory : IJobFactory
    {
        private static readonly ILog log = LogProvider.GetLogger(typeof (SimpleJobFactory));
        /// <summary>
        /// Called by the scheduler at the time of the trigger firing, in order to
        /// produce a <see cref="IJob" /> instance on which to call Execute.
        /// </summary>
        /// <remarks>
        /// It should be extremely rare for this method to throw an exception -
        /// basically only the case where there is no way at all to instantiate
        /// and prepare the Job for execution.  When the exception is thrown, the
        /// Scheduler will move all triggers associated with the Job into the
        /// <see cref="TriggerState.Error" /> state, which will require human
        /// intervention (e.g. an application restart after fixing whatever
        /// configuration problem led to the issue with instantiating the Job).
        /// </remarks>
        /// <param name="bundle">The TriggerFiredBundle from which the <see cref="IJobDetail" />
        ///   and other info relating to the trigger firing can be obtained.</param>
        /// <param name="scheduler"></param>
        /// <returns>the newly instantiated Job</returns>
        /// <throws>  SchedulerException if there is a problem instantiating the Job. </throws>
        public virtual IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
        {
            IJobDetail jobDetail = bundle.JobDetail;
            Type jobType = jobDetail.JobType;
            try
            {
                if (log.IsDebugEnabled())
                {
                    log.Debug($"Producing instance of Job '{jobDetail.Key}', class={jobType.FullName}");
                }
                return ObjectUtils.InstantiateType<IJob>(jobType);
            }
            catch (Exception e)
            {
                SchedulerException se = new SchedulerException($"Problem instantiating class '{jobDetail.JobType.FullName}'", e);
                throw se;
            }
        }
        /// <summary>
        /// Allows the job factory to destroy/cleanup the job if needed. 
        /// No-op when using SimpleJobFactory.
        /// </summary>
        public virtual void ReturnJob(IJob job)
        {
            var disposable = job as IDisposable;
            disposable?.Dispose();
        }
    }
}
//------------------节选自Quartz.Util.ObjectUtils类-------------------------
 public static T InstantiateType<T>(Type type)
{
     if (type == null)
     {
          throw new ArgumentNullException(nameof(type), "Cannot instantiate null");
     }
     ConstructorInfo ci = type.GetConstructor(Type.EmptyTypes);
     if (ci == null)
     {
          throw new ArgumentException("Cannot instantiate type which has no empty constructor", type.Name);
     }
     return (T) ci.Invoke(new object[0]);
}


但是很多情况下我们定义的Job很可能依赖第三方服务,就比如一线大佬文中NotificationJob依赖了ILogger<NotificationJob> 服务。


这样默认的SimpleJobFactory不能满足实例化要求, 考虑将Job任务作为依赖注入组件,加入依赖注入容器。


关键思路:


IScheduler 开放了JobFactory 属性,便于你应用自定义的Job工厂;


在自定义Job工厂中,使用ASP.NET Core依赖注入容器
IServiceProvider解析出特定的Job。


相关文章
|
9天前
|
开发框架 .NET C#
【专栏】理解.NET 技术,提升开发水平
【4月更文挑战第29天】本文介绍了.NET技术的核心概念和应用,包括其跨平台能力、性能优化、现代编程语言支持及Web开发等特性。文章强调了深入学习.NET技术、关注社区动态、实践经验及学习现代编程理念对提升开发水平的重要性。通过这些,开发者能更好地利用.NET构建高效、可维护的多平台应用。
|
消息中间件 NoSQL 关系型数据库
.NET 入门到高级路线
.NET 入门到高级路线
166 0
|
存储 JSON 缓存
.NET高级工程师面试经历
.NET高级工程师面试经历
150 0
|
Java Unix Linux
艾伟_转载:关于.NET VS JavaEE平台争论的沉思录
  最近关于.NET和java平台之间的争论似乎又热起来了,就我关注的两个社区,先是老赵的《为啥老赵不喜欢Java*语言*》。引发了博客园的大讨论,最近csdn又有人发博.Net与J2EE的快餐型比较,引发了空前的大讨论。
1207 0
|
SQL
一起谈.NET技术,技术详解:三招优化.NET中的锁(组团)
  在这篇文章中,我将使用三个方法处理乐观锁,包括ADO.NET数据集、SQL Server时间戳数据类型和新旧值检查,首先我们从并发谈起,探讨5个并发问题,然后从实际出发,利用这三种方法实现乐观锁。   为什么需要锁?  在多用户环境中,大家同时更新相同的记录可能会引发冲突,这个问题用专业的术语描述就叫做并发性。
1060 0
|
存储 SQL .NET
一起谈.NET技术,C#调试心经(续)
  由于上篇文章漏了一些比较重要的知识,在此文中补充。   断点篇   命中次数(Hit Counts)   右击断点,可以设置Hit Counts(命中次数),会弹出如下的对话框:   当条件满足的时候断点会被命中(即即将被执行),这个命中次数是断点被命中的次数。
1062 0
一起谈.NET技术,中软面试题-最新
中软的面试比较经典,也比较严格,一般有四轮,类似于微软的面试。中软面过以后,根据项目组,会推到美国微软那边运用live meeting & con-call 再面一次。以下是我的面试题及个人的小分析,拿出来和大家share一下。
805 0
.NET分布“.NET研究”式架构开发实战之一 故事起源
  前言:   本系列文章主要讲述一个实实在在的项目开发的过程,主要包含:提出问题,解决问题,架构设计和各个逻辑层的实现以及新问题的出现和代码的重构。本系列文章以故事的形式展开,而且文章列举的很多项目的名称,大家也不用太关心,很多都是虚拟的。
872 0
艾伟:[你必须知道的.NET] 开篇有益
本系列文章导航 [你必须知道的.NET] 开篇有益 [你必须知道的.NET] 第一回:恩怨情仇:is和as [你必须知道的.NET] 第二回:对抽象编程:接口和抽象类 [你必须知道的.NET] 第三回:历史纠葛:特性和属性 [你必须知道的.
1185 0