澳门新萄京官方网站-www.8455.com-澳门新萄京赌场网址

澳门新萄京官方网站学业调整,NET作业调整框架

2019-11-04 作者:www.8455.com   |   浏览(89)

Quartz.NET是二个十二分强大的作业调节框架,适用于各样准期试行的事情管理等,相通于WINDOWS自带的职分陈设程序,个中使用Cron表明式来落到实处各类依期触发条件是本身感到最佳欢腾的地点。

Quartz.NET 是三个开源的功课调治框架,是 Java 作业调解框架 Quartz 的.NET 版本,对于周期性的天职,其作业和触发器的组合,超级大的简化了代码的编排,许多时候我们只供给关心作业自身的逻辑。Quartz.NET 帮忙长久化、集群。Quartz.NET 3.0 已经上马扶植 .NET Core/.NET Standard 2.0。

在事先的小说《推荐介绍一个粗略、轻量、作用十一分强大的C#/ASP.NET准期任务推行微型机组件–FluentScheduler》和《简单、轻量、效率卓殊强盛的C#/ASP.NET定期调整任务施行管理组件–FluentScheduler之实例篇》中,我们认知和询问了FluentScheduler那款轻量的依期职务调治实施组件。今天再给大家介绍生机勃勃款有关定期职责调节推行的零件–Quartz.Net,Quartz.Net是Java版Quartz的.NET完成。

Quartz.NET首要接受上边多少个类:

澳门新萄京官方网站 1澳门新萄京官方网站学业调整,NET作业调整框架的一点小小的的包裹。系统布局

争持FluentScheduler完毕按时调解任务的行使简单,配置少的表征,Quartz.Net则配备稍稍复杂一些。上边大家就接入三个ASP.NET MVC网址应用程序的准期执行义务调节和测试的小实例来打探Quartz.Net的粗略用法,当然Webform的Web应用也是能够利用Quartz.Net 来作准时任务的。

IScheduler --调度器

Job 为作业的接口,JobDetail 用来陈诉 Job 的得以达成类及任何有关的静态音讯;Trigger 作为作业的依期管理工科具,四个Trigger 只好对应一个作业实例,而三个学业实例可对应八个 Trigger ;Scheduler 做为依期任务容器,它包罗了全数触发器和作业,每一个 Scheduler 都存有 JobDetail 和 Trigger的挂号,八个 Scheduler 中能够登记七个JobDetail 和八个 Trigger 。

率先,大家打开Visual Studio 二零一五,创制一个ASP.NET MVC的Web应用程序项目,命名称为QuartzNetMvcDemo

IJobDetail --作业职分

始建叁个基于 .NET Core 2.0 控制台程序,Nuget 安装 Quartz 就能够。

澳门新萄京官方网站 2

澳门新萄京官方网站,ITrigger --触发器

Install-Package Quartz

下一场经进度序包微型机调节台来设置Quartz.Net组件,如下:

假设大家友好使用Timer来写相通的依期执行义务程序的话,相应的大家应当有:(以下均为思忖,指标是让大家搞清楚Quartz.NET上边多个接口的涉嫌卡塔尔国

主要接口和类表明:

IScheduler :和调解器交互作用的首要性接口JobBuilder:定义 JobDetail 实例IJobDetail:定义 Job 实例及其它相关的静态音讯IJob:自定义的学业模块所要世襲的接口,调节器会调用这些实现TriggerBuilder:定义 Trigger 实例ITrigger:定义 Job 被触发的流年

澳门新萄京官方网站 3

ScheduleTimer --Timer,每秒推行贰回;

创设流程:
  1. 创立作业调节器 IScheduler
  2. 启航调解器
  3. 创建作业 IJobDetail
  4. 创设触发器 ITrigger
  5. 将作业和触发器参预到作业调治器中

Quartz.Net一个最简便易行义务起码包含三部分完结:job,trigger以至scheduler。在那之中job 是你要求在二个准时职务中实际试行的事务逻辑,trigger则鲜明job什么时候并依照何种准绳实行,最后job和trigger会被登记到 scheduler中,scheduler担负和睦job和trigger的周转。

TriggerClass --判定是或不是必要进行作业职务,ScheduleTimer 每实施三回,就应当新开线程调用TriggerClass成员 NeedExecute方法或性质;

代码完成:
private static async Task RunScheduler(){ // 创建作业调度器 ISchedulerFactory factory = new StdSchedulerFactory(); IScheduler scheduler = await factory.GetScheduler(); // 启动调度器 await scheduler.Start(); // 创建作业 IJobDetail job = JobBuilder.Create<HelloJob>() .WithIdentity("job1", "group1") .Build(); // 创建触发器,每10s执行一次 ITrigger trigger = TriggerBuilder.Create() .WithIdentity("trigger1", "group1") .StartNow() .WithSimpleSchedule(x => x .WithIntervalInSeconds .RepeatForever .Build(); // 加入到作业调度器中 await scheduler.ScheduleJob(job, trigger);}

学业贯彻类 HelloJob

public class HelloJob : IJob{ /// <summary> /// 作业调度定时执行的方法 /// </summary> /// <param name="context"></param> /// <returns></returns> public async Task Execute(IJobExecutionContext context) { await Console.Out.WriteLineAsync("Hello QuartzNet..."); }}

在Quartz.Net中,一个job即为一个类,为了让job能在Quartz.Net的连串中实行,我们必需兑现Quartz.Net提供的IJob接口的Execute方法,如本例所完成的IJob接口ReportJob类:

JobClass--具体的课业职务类,TriggerClass,若TriggerClass.NeedExecute再次回到true,那么就相应推行JobClass成员Execute方法;

代码表明:

因而 StdSchedulerFactory 获取到调治工厂 ISchedulerFactory,通过调解工厂的 GetScheduler 方法取得到二个调解器 scheduler 。开始化调解器 scheduler 之后, 就足以运营、 备用、 关闭。

经过 JobBuilder 创制贰个 IJobDetail 作业实际情况 ,钦点一个 IJob 的贯彻类 HelloJob ,同时钦定了作业详细的情况标志的键名和组名。

经过 TriggerBuilder 创设贰个 ITrigger 触发器,钦定了那么些触发器标志的键名和组名,触发器唯有在起步状态技能工作,这里安装了 StartNow,同不时间安装了触发器的实行时间,每间隔10s施行一回。当 Trigger 触发的时候, HelloJob 的Execute 方法就能够在调节器 scheduler 的干活线程中推行,这里设置的 RepeatForever 是指在脚下照顾进度内再次推行,假使程序被关门了,那一定不会继续实施。

using System;using Quartz;using System.IO;namespace QuartzNetMvcDemo{  public class ReportJob : IJob  {    public void Execute(IJobExecutionContext context)    {      var reportDirectory = string.Format("~/reports/{0}/", DateTime.Now.ToString("yyyy-MM"));      reportDirectory = System.Web.Hosting.HostingEnvironment.MapPath(reportDirectory);      if (!Directory.Exists(reportDirectory))      {        Directory.CreateDirectory(reportDirectory);      }      var dailyReportFullPath = string.Format("{0}report_{1}.log", reportDirectory, DateTime.Now.Day);      var logContent = string.Format("{0}==>>{1}{2}", DateTime.Now, "create new log.", Environment.NewLine);      File.AppendAllText(dailyReportFullPath, logContent);    }  }}

好了,有关Quartz.NET的牵线特别之多,作者那边不在多说,下边将珍视介绍怎么着兑现伪AOP写LOG成效。

奉行结果:

澳门新萄京官方网站 4实践结果

  • Quartz.NET Documentation
  • 案例 Demo-QuartzNetTest

Execute方法有叁个IJobExecutionContext的接口对象作为参数,这么些参数富含了定义这么些类的job的安排消息。当然,作为示范,在本例中,我们并未有接受到那些参数。

AOP不知道,请点击此处了解。

接下去,大家须求贯彻三个trigge,示例代码如下:

Quartz.NET尽管已经集成了log4net的写日记功用,只需在Config配置好就能够,但本身感到框架之中写的日志不相符作者的渴求,故小编必要根据实际专门的学问须要在少数规范才举办写LOG,故才有了那篇小说。

using Quartz;using Quartz.Impl;namespace QuartzNetMvcDemo{  public class ReportJobScheduler  {    public static void Start()    {      IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();      scheduler.Start();      IJobDetail job = JobBuilder.Create<ReportJob>;      ITrigger trigger = TriggerBuilder.Create()        .WithIdentity("triggerName", "groupName")        .WithSimpleSchedule(t =>          t.WithIntervalInSeconds           .RepeatForever           .Build();      scheduler.ScheduleJob(job, trigger);    }  }}

以下是达成了一个Job包裹类,也得以作为是Job的代理类,完整代码如下:

以此代码片段你能够放在你项近些日子后相继的其他能够被调用的地点,类名你也足以随便取,那从没怎么关系的。只要在利用那些类时精确援引就可以。

    [DisallowConcurrentExecution]
    public class JobWraper<TJob> : IJob where TJob : IJob, new()
    {
        private static int syncFlag = 0;
        private IJob jobInner = null;

        public JobWraper()
        {
            jobInner = Activator.CreateInstance<TJob>();
        }

        public void Execute(IJobExecutionContext context)
        {
            if (Interlocked.Increment(ref syncFlag) != 1) return; //忙判断
            try
            {
                jobInner.Execute(context);
            }
            catch (Exception ex)
            {
                Master.WriteMsg(context.JobDetail.Key   "执行异常:"   ex.Message   Environment.NewLine   ex.StackTrace, true, true);
            }

            Interlocked.Exchange(ref syncFlag, 0); //解除忙
        }

在代码中,大家接纳StdSchedulerFactory.GetDefaultScheduler()创制了二个scheduler 并随时运行了这些调治器,然后成立了八个简易的Quartz.Net触发器并对那几个触发器实行了一些安插:钦赐了触发器的称号为triggerName,触发器 的分组为groupName,内定每5秒触发一遍并直接循环触发。最终经过scheduler.ScheduleJob()方法把job和 trigger注册到了调治器中,这样二个完完全全的定时职分就定制达成了。

代码比非常粗略,兴味索然的人都看得懂,作者只是说入眼:

提起底,我们还要做的生机勃勃件业务正是运维大家定制好的准时职责,我们把那些职务放到项近期后相继的全局cs文件(Global.asax)的Application_Start方法中来施行:

1.syncFlag静态字段,目标是用来标志是不是忙依旧不忙,1表示不忙,其余代表忙,Interlocked.Increment与Interlocked.Exchange的用法是原子级的,确定保障每一次只可以有叁个线程进行操作,相似于SQL中的独自占领锁,与lock有一点近似,但又分歧,若是用lock将全部实行都用大括号包起来,那么锁的限量相比较广並且不易调控,而Interlocked只必要在急需的时候才独自据有,何况独自占领的时光相当短,别的大部份时间都以常规,并且更易可控,那正是作者心爱用她的来由。

using System.Web.Mvc;using System.Web.Optimization;using System.Web.Routing;namespace QuartzNetMvcDemo{  public class MvcApplication : System.Web.HttpApplication  {    protected void Application_Start()    {      AreaRegistration.RegisterAllAreas();      FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);      RouteConfig.RegisterRoutes(RouteTable.Routes);      BundleConfig.RegisterBundles(BundleTable.Bundles);            //启动定时任务      ReportJobScheduler.Start();    }  }}

2.怎么标志忙与不忙,原因是小编必须确认保障每一趟施行的政工逻辑能够实行到位,而毫无现身未奉行到位,下二遍的试行点又到了,造成多次竟然重复实行。

好了,今后具有的操作皆是做到,按下F5运营大家的ASP.NET MVC按期职分调解执行示例程序。过一分钟去开垦我们的日记文件,若是程序不奇怪运作,那么您将看见如下的日记:

2.为啥要卷入,原因是自家不想每一个Job类里面都写try catch极度捕获及忙与不忙的论断,那样经常类只需当心专门的职业管理就能够。至于被包裹的类不必然非要IJob接口,能够自定义各个接口,但显著要有无参构造函数,否则就不恐怕创制包裹的类的实例了。

澳门新萄京官方网站 5

通过上边包车型客车执教,大家应该都知情了,下边是自己为了方便集成管理Job,封装了叁个JobManager职责管理类,完整代码如下:(代码比较简单,不再表达)

如何,Quartz.Net完成的准期实施职分调节是否也比较轻巧呢?当然,那只是Quartz.Net的简要示例,Quartz.Net还应该有广大越来越高档的机能,如援救配置文件的作业调节,支持cron的学业周期等。

    public class JobManager
    {

        private IScheduler scheduler = null;
        private int schedulerState = 0;


        public Dictionary<string, JobWithTrigger> JobTriggers
        {
            get;
            private set;
        }

        private IScheduler GetAScheduler()
        {
            var stdSchedulerFactory = new StdSchedulerFactory();
            scheduler = stdSchedulerFactory.GetScheduler();
            return scheduler;
        }

        public JobManager()
        {
            scheduler = GetAScheduler();
            JobTriggers = new Dictionary<string, JobWithTrigger>();
        }

        public JobWithTrigger CreateJobWithTrigger<TJob>(string cronExpr, IDictionary<string, object> jobData = null) where TJob : IJob
        {
            var jobType = typeof(TJob);
            string jobTypeName = jobType.Name;
            if (jobType.IsGenericType)
            {
                jobTypeName = jobType.GetGenericArguments()[0].Name;
            }

            IJobDetail job = null;

            if (jobData == null)
                job = JobBuilder.Create<TJob>().WithIdentity(jobTypeName).Build();
            else
                job = JobBuilder.Create<TJob>().WithIdentity(jobTypeName).UsingJobData(new JobDataMap(jobData)).Build();

            ITrigger trigger = TriggerBuilder.Create().WithIdentity(jobTypeName   "-Trigger").ForJob(job).StartNow().WithCronSchedule(cronExpr).Build();

            var jt = new JobWithTrigger(job, trigger);
            JobTriggers[jt.Key] = jt;

            return jt;
        }

        public void ScheduleJobs(params JobWithTrigger[] jts)
        {
            if (scheduler.IsShutdown)
            {
                scheduler = GetAScheduler();
            }

            foreach (var jt in jts)
            {
                scheduler.ScheduleJob(jt.JobDetail, jt.Trigger);
            }
        }


        public void ScheduleJobs(params string[] jtKeys)
        {
            var jts = JobTriggers.Where(t => jtKeys.Contains(t.Key)).Select(t => t.Value).ToArray();
            ScheduleJobs(jts);
        }

        public void UnscheduleJobs(params TriggerKey[] triggerKeys)
        {
            scheduler.UnscheduleJobs(triggerKeys.ToList());
        }

        public void UnscheduleJobs(params string[] jtKeys)
        {
            var triggerKeyObjs = JobTriggers.Where(t => jtKeys.Contains(t.Key)).Select(t => t.Value.Trigger.Key).ToArray();
            UnscheduleJobs(triggerKeyObjs);
        }

        public int State
        {
            get
            {
                return schedulerState;  //0:未开始,1:开始,2:暂停,3:恢复,-1:停止
            }
        }


        [MethodImpl(MethodImplOptions.Synchronized)]
        public void Start()
        {
            if (schedulerState > 0) return;
            scheduler.Start();
            schedulerState = 1;
            Master.WriteMsg("AutoTimingExecSystem程序已启动,所有任务按计划开始执行。", false, true);
        }


        [MethodImpl(MethodImplOptions.Synchronized)]
        public void Stop()
        {
            if (schedulerState <= 0) return;
            scheduler.Clear();
            scheduler.Shutdown();
            schedulerState = -1;
            Master.WriteMsg("AutoTimingExecSystem程序已停止,所有任务停止执行。", false, true);
        }


        [MethodImpl(MethodImplOptions.Synchronized)]
        public void Pause()
        {
            if (schedulerState != 1) return;
            scheduler.PauseAll();
            schedulerState = 2;
            Master.WriteMsg("所有任务被取消或暂停执行。", false, true);
        }


        [MethodImpl(MethodImplOptions.Synchronized)]
        public void Resume()
        {
            if (schedulerState != 2) return;
            scheduler.ResumeAll();
            schedulerState = 1;
            Master.WriteMsg("所有任务重新恢复执行。", false, true);
        }

    }

生龙活虎旦你认为本文对您有效的话,请点一下“推荐”吧,那样能够更有效地扶持到别人噢!!!

JobWithTrigger:职分与触发器关联类

    [Serializable]
    public class JobWithTrigger
    {
        public JobWithTrigger()
        {
            this.Key = Guid.NewGuid().ToString("N");
        }

        public JobWithTrigger(IJobDetail job, ITrigger trigger)
            : this()
        {
            this.JobDetail = job;
            this.Trigger = trigger;
        }

        public IJobDetail JobDetail
        { get; set; }

        public ITrigger Trigger
        { get; set; }

        public string JobName
        {
            get
            {
                return this.JobDetail.Key.Name;
            }
        }

        public string TriggerName
        {
            get
            {
                return this.Trigger.Key.Name;
            }
        }

        public string Key
        {
            get;
            private set;
        }
    }

用法比较容易,示例代码如下:

var jobManager = new JobManager();
var jt=jobManager.CreateJobWithTrigger<JobWraper<TestJob>>("0/5 * * * * ?");

//这里面可以将jt的保存或显示到任务界面上...

jobManager.ScheduleJobs(JobWithTrigger的KEY数组 或 JobWithTrigger对象)

jobManager.Start(); 

jobManager.Stop();

jobManager扶植每每开启与关闭。

本文由澳门新萄京官方网站发布于www.8455.com,转载请注明出处:澳门新萄京官方网站学业调整,NET作业调整框架

关键词: