您的位置:新葡亰496net > 奥门新萄京娱乐场 > 学业调治,NET作业调治框架的一点小小的的卷入

学业调治,NET作业调治框架的一点小小的的卷入

发布时间:2019-10-05 12:44编辑:奥门新萄京娱乐场浏览(140)

    Quartz.NET是一个非常强大的作业调度框架,适用于各种定时执行的业务处理等,类似于WINDOWS自带的任务计划程序,其中运用Cron表达式来实现各种定时触发条件是我认为最为惊喜的地方。

    关于Quartz.NET作业调度框架的一点小小的封装,实现伪AOP写LOG功能,quartz.netaop

    Quartz.NET是一个非常强大的作业调度框架,适用于各种定时执行的业务处理等,类似于WINDOWS自带的任务计划程序,其中运用Cron表达式来实现各种定时触发条件是我认为最为惊喜的地方。

    Quartz.NET主要用到下面几个类:

    IScheduler --调度器

    IJobDetail --作业任务

    ITrigger --触发器

    如果我们自己采用Timer来写类似的定时执行任务程序的话,相应的我们应该有:(以下均为设想,目的是让大家搞清楚Quartz.NET上面三个接口的关系)

    ScheduleTimer --Timer,每秒执行一次;

    TriggerClass --判断是否需要执行作业任务,ScheduleTimer 每执行一次,就应该新开线程调用TriggerClass成员 NeedExecute方法或属性;

    JobClass--具体的作业任务类,TriggerClass,若TriggerClass.NeedExecute返回true,那么就应该执行JobClass成员Execute方法;

    好了,有关Quartz.NET的介绍非常之多,我这里不在多说,下面将主要介绍如何实现伪AOP写LOG功能。

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

    Quartz.NET虽然已经集成了log4net的写日志功能,只需在Config配置好即可,但我觉得框架里面写的日志不符合我的要求,故我需要按照实际业务需要在某些条件才进行写LOG,故才有了这篇文章。

    以下是实现了一个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); //解除忙
            }
    

    代码很简单,一般人都看得懂,我只是说重点:

    1.syncFlag静态字段,目的是用来标记是否忙或者不忙,1代表不忙,其它代表忙,Interlocked.Increment与Interlocked.Exchange的用法是原子级的,确保每次只能有一个线程进行操作,类似于SQL中的独占锁,与lock有点相同,但又不同,如果用lock将整个执行都用大括号包起来,那么锁的范围比较广而且不易控制,而Interlocked只需要在需要的时候才独占,而且独占的时间非常短,其他大部份时间都是正常,而且更易可控,这就是我喜欢用他的原因。

    2.为什么标记忙与不忙,原因是我必需确保每次执行的业务逻辑能够执行完成,而不要出现未执行完成,下一次的执行点又到了,造成多次甚至重复执行。

    2.为什么要包裹,原因是我不想每个Job类里面都写try catch异常捕获及忙与不忙的判断,这样普通类只需专注业务处理即可。至于被包裹的类不一定非要IJob接口,可以自定义各类接口,但一定要有无参构造函数,否则就无法创建包裹的类的实例了。

    通过上面的讲解,大家应该都明白了,下面是我为了便于集成管理Job,封装了一个JobManager任务管理类,完整代码如下:(代码比较简单,不再说明)

        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支持反复开启与关闭。

    Quartz.NET是一个非常强大的作业调度框架,适用于各种定时执行...

    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体系结构

    相对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 2015,创建一个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);
            }
    
        }
    

    如果你觉得本文对你有用的话,请点一下“推荐”吧,这样可以更有效地帮助到他人噢!!!

    学业调治,NET作业调治框架的一点小小的的卷入。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支持反复开启与关闭。

    本文由新葡亰496net发布于奥门新萄京娱乐场,转载请注明出处:学业调治,NET作业调治框架的一点小小的的卷入

    关键词:

上一篇:新葡亰496net安装环境,python前世今生

下一篇:没有了