关于Quartz .net 使用

这两天做一个实时任务推送,本来想着说用线程或者定时器。后面发现Quartz .net这个强大的定时任务框架,然后记录下

Quartz .Net就是一个定时任务推送的开源框架

下载地址:Quartz .net下载地址:https://www.quartz-scheduler.net/download.html

Quartz有两种存储机制,一是存缓存

1.配置文件   

<?xml version="1.0" encoding="UTF-8"?>

<!-- This file contains job definitions in schema version 2.0 format -->

<job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">

  <processing-directives>
    <overwrite-existing-data>true</overwrite-existing-data>
  </processing-directives>

  <schedule>

    <job>
      <name>sampleJob</name>
      <group>sampleGroup</group>
      <description>Sample job for Quartz Server</description>
      <job-type>Quartz.Server.SampleJob, Quartz.Server</job-type>
      <durable>true</durable>
      <recover>false</recover>
      <job-data-map>
        <entry>
          <key>key1</key>
          <value>value1</value>
        </entry>
        <entry>
          <key>key2</key>
          <value>value2</value>
        </entry>
      </job-data-map>
    </job>

    <trigger>
      <simple>
        <name>sampleSimpleTrigger</name>
        <group>sampleSimpleGroup</group>
        <description>Simple trigger to simply fire sample job</description>
        <job-name>sampleJob</job-name>
        <job-group>sampleGroup</job-group>
        <misfire-instruction>SmartPolicy</misfire-instruction>
        <repeat-count>-1</repeat-count>
        <repeat-interval>10000</repeat-interval>
      </simple>
    </trigger>
    <trigger>
      <cron>
        <name>sampleCronTrigger</name>
        <group>sampleCronGroup</group>
        <description>Cron trigger to simply fire sample job</description>
        <job-name>sampleJob</job-name>
        <job-group>sampleGroup</job-group>
        <misfire-instruction>SmartPolicy</misfire-instruction>
        <cron-expression>0/10 * * * * ?</cron-expression>
      </cron>
    </trigger>
    <trigger>
      <calendar-interval>
        <name>sampleCalendarIntervalTrigger</name>
        <group>sampleCalendarIntervalGroup</group>
        <description>Calendar interval trigger to simply fire sample job</description>
        <job-name>sampleJob</job-name>
        <job-group>sampleGroup</job-group>
        <misfire-instruction>SmartPolicy</misfire-instruction>
        <repeat-interval>15</repeat-interval>
        <repeat-interval-unit>Second</repeat-interval-unit>
      </calendar-interval>
    </trigger>
  </schedule>
</job-scheduling-data>


2:定义Quartz任务管理工厂

using Quartz;
using Quartz.Impl;
using Quartz.Impl.Triggers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Berry.SignalRService.Schedu.Jobs
{
    /// <summary>
    /// Quartz任务管理类
    /// </summary>
    public static class QuartzUtil
    {
        private static ISchedulerFactory sf = null;
        private static IScheduler sched = null;

        static QuartzUtil()
        {
            sf = new StdSchedulerFactory();
            sched = sf.GetScheduler();
            sched.Start();
        }

        /// <summary>
        /// 添加Job 并且以定点的形式运行 不带参数的cron表达式新建job
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="JobName"></param>
        /// <param name="CronTime"></param>
        /// <returns></returns>
        public static DateTimeOffset AddJob<T>(string JobName, string CronTime) where T : IJob
        {
            return AddJob<T>(JobName, CronTime, null);
        }

        /// <summary>
        /// 添加Job 并且以定点的形式运行  参数为Cron表达式,可传参数。目前支持一个参数,可加
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="JobName">keyName</param>
        /// <param name="CronTime">Cron表达式</param>
        /// <param name="jobDataMap">传递的参数,目前用于ConnId</param>
        /// <returns></returns>
        public static DateTimeOffset AddJob<T>(string JobName, string CronTime, string connIds) where T : IJob
        {
            IJobDetail jobCheck = JobBuilder.Create<T>().WithIdentity(JobName, JobName + "_Group").UsingJobData("connIds", connIds).Build();
            ICronTrigger CronTrigger = new CronTriggerImpl(JobName + "_CronTrigger", JobName + "_TriggerGroup", CronTime);
            return sched.ScheduleJob(jobCheck, CronTrigger);
        }

      

        /// <summary>
        /// 添加Job 并且以周期的形式运行
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="JobName"></param>
        /// <param name="SimpleTime">毫秒数</param>
        /// <returns></returns>
        public static DateTimeOffset AddJob<T>(string JobName, int SimpleTime) where T : IJob
        {
            return AddJob<T>(JobName, DateTime.UtcNow.AddMilliseconds(1), TimeSpan.FromMilliseconds(SimpleTime));
        }

        /// <summary>
        /// 添加Job 并且以周期的形式运行
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="JobName"></param>
        /// <param name="SimpleTime">毫秒数</param>
        /// <returns></returns>
        public static DateTimeOffset AddJob<T>(string JobName, DateTimeOffset StartTime, int SimpleTime) where T : IJob
        {
            return AddJob<T>(JobName, StartTime, TimeSpan.FromMilliseconds(SimpleTime));
        }

        /// <summary>
        /// 添加Job 并且以周期的形式运行
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="JobName"></param>
        /// <param name="SimpleTime"></param>
        /// <returns></returns>
        public static DateTimeOffset AddJob<T>(string JobName, DateTimeOffset StartTime, TimeSpan SimpleTime) where T : IJob
        {
            return AddJob<T>(JobName, StartTime, SimpleTime, new Dictionary<string, object>());
        }

        /// <summary>
        /// 添加Job 并且以周期的形式运行
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="JobName"></param>
        /// <param name="StartTime"></param>
        /// <param name="SimpleTime">毫秒数</param>
        /// <param name="jobDataMap"></param>
        /// <returns></returns>
        public static DateTimeOffset AddJob<T>(string JobName, DateTimeOffset StartTime, int SimpleTime, string MapKey, object MapValue) where T : IJob
        {
            Dictionary<string, object> map = new Dictionary<string, object>();
            map.Add(MapKey, MapValue);
            return AddJob<T>(JobName, StartTime, TimeSpan.FromMilliseconds(SimpleTime), map);
        }

        /// <summary>
        /// 添加Job 并且以周期的形式运行
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="JobName">JobKey</param>
        /// <param name="StartTime">开始时间</param>
        /// <param name="SimpleTime">时间差</param>
        /// <param name="jobDataMap">传递的参数</param>
        /// <returns></returns>
        public static DateTimeOffset AddJob<T>(string JobName, DateTimeOffset StartTime, TimeSpan SimpleTime, Dictionary<string, object> map) where T : IJob
        {
            IJobDetail jobCheck = JobBuilder.Create<T>().WithIdentity(JobName, JobName + "_Group").Build();
            jobCheck.JobDataMap.PutAll(map);
            ISimpleTrigger triggerCheck = new SimpleTriggerImpl(JobName + "_SimpleTrigger", JobName + "_TriggerGroup",
                                        StartTime,
                                        null,
                                        SimpleTriggerImpl.RepeatIndefinitely,
                                        SimpleTime);
            return sched.ScheduleJob(jobCheck, triggerCheck);
        }

        /// <summary>
        /// 修改触发器时间,需要job名,以及修改结果
        /// CronTriggerImpl类型触发器
        /// </summary>
        public static void UpdateTime(string jobName, string CronTime)
        {
            TriggerKey TKey = new TriggerKey(jobName + "_CronTrigger", jobName + "_TriggerGroup");
            CronTriggerImpl cti = sched.GetTrigger(TKey) as CronTriggerImpl;
            cti.CronExpression = new CronExpression(CronTime);
            sched.RescheduleJob(TKey, cti);
        }

        /// <summary>
        /// 修改触发器时间,需要job名,以及修改结果
        /// SimpleTriggerImpl类型触发器
        /// </summary>
        /// <param name="jobName"></param>
        /// <param name="SimpleTime">分钟数</param>
        public static void UpdateTime(string jobName, int SimpleTime)
        {
            UpdateTime(jobName, TimeSpan.FromMinutes(SimpleTime));
        }

        /// <summary>
        /// 修改触发器时间,需要job名,以及修改结果
        /// SimpleTriggerImpl类型触发器
        /// </summary>
        public static void UpdateTime(string jobName, TimeSpan SimpleTime)
        {
            TriggerKey TKey = new TriggerKey(jobName + "_SimpleTrigger", jobName + "_TriggerGroup");
            SimpleTriggerImpl sti = sched.GetTrigger(TKey) as SimpleTriggerImpl;
            sti.RepeatInterval = SimpleTime;
            sched.RescheduleJob(TKey, sti);
        }

        /// <summary>
        /// 暂停所有Job
        /// </summary>
        public static void PauseAll()
        {
            sched.PauseAll();
        }

        /// <summary>
        /// 恢复所有Job
        /// </summary>
        public static void ResumeAll()
        {
            sched.ResumeAll();
        }

        /// <summary>
        /// 暂停某个任务
        /// </summary>
        /// <param name="JobName"></param>
        public static void PauseJob(string JobName)
        {
            JobKey jk = new JobKey(JobName);
            sched.PauseJob(jk);
        }
        
        /// <summary>
        /// 恢复指定的Job
        /// </summary>
        /// <param name="JobKey"></param>
        public static void ResumeJob(string JobName)
        {
            JobKey jk = new JobKey(JobName);
            sched.ResumeJob(jk);
        }
      
        /// <summary>
        /// 删除Job
        /// </summary>
        /// <param name="JobName"></param>
        public static void DeleteJob(string JobName)
        {
            JobKey jk = new JobKey(JobName);
            sched.DeleteJob(jk);
        }

        /// <summary>
        /// 卸载定时器
        /// </summary>
        /// <param name="waitForJobsToComplete">是否等待job执行完成</param>
        public static void Shutdown(bool waitForJobsToComplete)
        {
            sched.Shutdown(waitForJobsToComplete);
        }
    }
}


这个是我定义的Quartz的工厂类,写了几种方式的建立任务,一般来说都是用的cron表达式来建立的,因为呢这样比较方便,灵活。就是下面这个方式

  public static DateTimeOffset AddJob <T>(string JobName,string CronTime,string connIds)其中T:IJob
        {
            IJobDetail jobCheck = JobBuilder.Create<T>().WithIdentity(JobName, JobName + "_Group").UsingJobData("connIds", connIds).Build();
            ICronTrigger CronTrigger = new CronTriggerImpl(JobName + "_CronTrigger", JobName + "_TriggerGroup", CronTime);
            return sched.ScheduleJob(jobCheck, CronTrigger);
        }

IJobDetail是用于创建一个Job详情,包括Job名称,Job组,Job参数 “connIds”就是我传递的参数

ICronTrigger就是写入cron表达式的,关于cron表达式的格式参考下这个

https://blog.csdn.net/li295214001/article/details/52065634

然后工厂类就定义好了,其他的扩展方法还有很多,就没有一一说明了

3.定义Job

using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using Quartz;
using System.Collections.Generic;

namespace Berry.SignalRService.Schedu.Jobs
{
    /// <summary>
    /// 赛事推送
    /// </summary>
    public class MatchJob : IJob
    {
        /// <summary>
        /// 系统缓存
        /// </summary>
        private readonly Cache.WebCache _cache = new Cache.WebCache();

        private IHubConnectionContext<dynamic> Clients { get; set; }

        private MatchJob(IHubConnectionContext<dynamic> clients)
        {
            Clients = clients;
        }

        /// <summary>
        /// 执行函数
        /// </summary>
        /// <param name="context"></param>
        public void Execute(IJobExecutionContext context)
        {
            try
            {
                JobKey jobkey = context.JobDetail.Key;
                //系统缓存的之前已经查出来的数据
                var cachedata = _cache.GetCache<string>(jobkey.ToString() + "__JobDataCache");
                //datamap里存的数据,现在是存的connid
                string connIds = context.JobDetail.JobDataMap.GetString("connIds");
                string[] connidList = connIds.Split(',');

                //TODO  从数据库查询数据最新加的数据然后添加到__JobDataCache缓存
                cachedata += "";




                //将查出来的数据写入到缓存,覆盖之前的缓存
                _cache.WriteCache(cachedata, jobkey.ToString() + "__JobDataCache");

                //向所有开启服务的客户端推送查询到的数据
                foreach (var connId in connidList)
                {
                    Clients.Client(connId).BroadcastJobOpened(cachedata);
                }
               
            }
            catch (System.Exception e)
            {
                throw new HubException("发送消息发生异常.", new {  message = e.Message });

            }

        }
    }


    /// <summary>
    /// 新闻推送
    /// </summary>
    public class NewsJob : IJob
    {
        /// <summary>
        /// 系统缓存
        /// </summary>
        private readonly Cache.WebCache _cache = new Cache.WebCache();

        private IHubConnectionContext<dynamic> Clients { get; set; }

        private NewsJob(IHubConnectionContext<dynamic> clients)
        {
            Clients = clients;
        }

        /// <summary>
        /// 执行函数
        /// </summary>
        /// <param name="context"></param>
        public void Execute(IJobExecutionContext context)
        {
            try
            {
                JobKey jobkey = context.JobDetail.Key;
                //系统缓存的之前已经查出来的数据
                var cachedata = _cache.GetCache<string>(jobkey.ToString() + "__JobDataCache");
                //datamap里存的数据,现在是存的connid
                string connIds = context.JobDetail.JobDataMap.GetString("connIds");
                string[] connidList = connIds.Split(',');

                //TODO  从数据库查询数据最新加的数据然后添加到__JobDataCache缓存
                cachedata += "";




                //将查出来的数据写入到缓存,覆盖之前的缓存
                _cache.WriteCache(cachedata, jobkey.ToString() + "__JobDataCache");

                //向所有开启服务的客户端推送查询到的数据
                foreach (var connId in connidList)
                {
                    Clients.Client(connId).BroadcastJobOpened(cachedata);
                }

            }
            catch (System.Exception e)
            {
                throw new HubException("发送消息发生异常.", new { message = e.Message });

            }

        }
    }

    /// <summary>
    /// 系统推送
    /// </summary>
    public class SysJob : IJob
    {
        /// <summary>
        /// 系统缓存
        /// </summary>
        private readonly Cache.WebCache _cache = new Cache.WebCache();

        private IHubConnectionContext<dynamic> Clients { get; set; }

        private SysJob(IHubConnectionContext<dynamic> clients)
        {
            Clients = clients;
        }

        /// <summary>
        /// 执行函数
        /// </summary>
        /// <param name="context"></param>
        public void Execute(IJobExecutionContext context)
        {
            try
            {
                JobKey jobkey = context.JobDetail.Key;
                //系统缓存的之前已经查出来的数据
                var cachedata = _cache.GetCache<string>(jobkey.ToString() + "__JobDataCache");
                //datamap里存的数据,现在是存的connid
                string connIds = context.JobDetail.JobDataMap.GetString("connIds");
                string [] connidList = connIds.Split(',');

                // TODO从数据库查询数据最新加的数据然后添加到__JobDataCache缓存
                cachedata + =“”;



 //将查出来的数据写入到缓存,覆盖之前的缓存 _cache.WriteCache(cachedata,jobkey.ToString()+“__ JobDataCache”); 
 //向所有开启服务的客户端推送查询到的数据 foreach(connidList中的var connId) {  Clients.Client(CONNID).BroadcastJobOpened(cachedata);  } 
 }  catch(System.Exception e) {  抛出新的HubException(“发送消息发生异常。”,new {message = e.Message}); 
 } 
 }  }  }

有几种类型的工作单独定义,执行函数可能不同。但是都要集成IJob类。

在执行函数里执行,可以获取到你传递的一个的JobDetail中的各个参数,用于你使用。


这样建立后就没有问题了,然后我用的实时推送是用的SignalR的直接推送给对应的用户的。做实时推送的话可以去看看,之后我也会更新一篇SignalR的用法~~

发现问题的欢迎大家指出来交流

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值