net的粗略包装,NET营造友好的动态作业调度器

分享1个在先封装的Quartz.net类。

新建1个QuartzClass类库项目。nuget控制台输入

   

   

新建2个QuartzClass类库项目。nuget控制台输入

亚洲必赢官网 1

 

 

亚洲必赢官网 2

image.png

  在平凡的开支中,运营定时职务基本三月经是很宽泛的须求了,能够由此windows服务+timer组件来落实,也足以运用第二方框架来集成,Quartz.NET正是壹款从JAVA的Quartz移植过来的七个没有错的功课调度组件,不过当大家把作业都写好,并配置形成的时候,管理成为了很麻烦的事务,由此作者依据Quartz.NET,又简约做了刹那间封装,来落成作业动态管理。

  在平凡的开销中,运维定时职分基本寒食经是很广泛的须要了,能够经过windows服务+timer组件来兑现,也得以行使第壹方框架来集成,Quartz.NET正是一款从JAVA的Quartz移植过来的三个不利的作业调度组件,可是当大家把作业都写好,并铺排形成的时候,管理变成了很麻烦的政工,由此笔者依照Quartz.NET,又简约做了一下封装,来落到实处作业动态管理。

image.png

添加Quartz.net的引用。
作者们新建三个JobBase.cs文件,里面有叁个Run方法。之后有所的Job都需再三再四那么些基类,并完毕Run方法。
<pre>
namespace LY.QuartzClass
{

  首先作业动态管理包括以下几个主题点

  首先作业动态管理包括以下多少个宗旨点

 

public abstract class JobBase
{
    public abstract void Run();

}
  1. 应用程序动态加载器
  2. 学业管理(运营)池
  3. 动态运行/截止/卸载作业
  1. 应用程序动态加载器
  2. 学业管理(运营)池
  3. 动态运维/停止/卸载作业

添加Quartz.net的引用。
我们新建二个JobBase.cs文件,里面有二个Run方法。之后全数的Job都需后续那些基类,并促成Run方法。

}
</pre>

 

 

namespace LY.QuartzClass
{
public abstract class JobBase
{
    public abstract void Run();

}
}

然后新增贰个JobInstance.cs类。那一个类主要完成IJob接口。
<pre>
using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
net的粗略包装,NET营造友好的动态作业调度器。using System.Text;

  Quzrtz.NET怎么用本身那里就不再讲解了,百度上众多。

  Quzrtz.NET怎么用自个儿那里就不再讲解了,百度上过多。

 

namespace LY.QuartzClass
{
public class JobInstance : IJob
{
public void Execute(IJobExecutionContext context)
{
IDictionary<string, object> jobs = context.JobDetail.JobDataMap;
if (jobs != null)
{
foreach (var item in jobs.Values)
{
try
{
JobBase jobObj = item as JobBase;
jobObj.Run();
}
catch
{
}
}
}
}
}
}
</pre>
在JobInstance类的Execute方法中,我们从JobDataMap中取出JobBase实体,并执行Run方法。

 

 

随后新增三个JobInstance.cs类。那一个类主要达成IJob接口。

上面大家新增二个JobManager.cs类,类内唯有多少个简练的AddJob方法
<pre>
using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

  重要有四个主导模块,Job,Trigger和Schedule,

  主要有多个着力模块,Job,Trigger和Schedule,

using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LY.QuartzClass
{
public class JobInstance : IJob
{
public void Execute(IJobExecutionContext context)
{
IDictionary<string, object> jobs = context.JobDetail.JobDataMap;
if (jobs != null)
{
foreach (var item in jobs.Values)
{
try
{
JobBase jobObj = item as JobBase;
jobObj.Run();
}
catch
{
}
}
}
}
}
}

namespace LY.QuartzClass
{
public class JobManage
{
IScheduler schedudler;
public JobManage()
{
schedudler = StdSchedulerFactory.GetDefaultScheduler();
schedudler.Start();
}

     
Job正是每3个作业,Trigger便是作业执行策略(多久执行一遍等),Schedule则把Job和Tigger装载起来

     
Job正是每一个功课,Trigger正是作业执行政策(多久执行一遍等),Schedule则把Job和Tigger装载起来

 

    public void AddJob<T>(int Second) where T : JobBase
    {

        JobBase jbobj = Activator.CreateInstance<T>();
        IDictionary<string, object> jbData = new Dictionary<string, object>();
        jbData.Add("name", jbobj);

        IJobDetail job1 = JobBuilder.Create<JobInstance>()
            .SetJobData(new JobDataMap(jbData)).Build();

        ITrigger trigger1 = TriggerBuilder.Create()
            .StartNow()
            .WithSimpleSchedule(x => x.WithIntervalInSeconds(Second)
            .RepeatForever()).Build();

        schedudler.ScheduleJob(job1, trigger1);

    }

   public void AddJob<T>(string rule) where T : JobBase
    {
        JobBase jbInstance = Activator.CreateInstance<T>();
        IDictionary<string, object> jbData = new Dictionary<string, object>();
        jbData.Add("name", jbInstance);

        IJobDetail job1 = JobBuilder.Create<JobInstance>()
            .SetJobData(new JobDataMap(jbData)).Build();

        ITrigger trigger1 = TriggerBuilder.Create()
            .StartNow()
            .WithCronSchedule(rule).Build();

        schedudler.ScheduleJob(job1, trigger1);
    }
}

  Job和Tigger能够专擅搭配装载到Schedule里面运营

  Job和Tigger能够任意搭配装载到Schedule里面运转

在JobInstance类的Execute方法中,我们从JobDataMap中取出JobBase实体,并执行Run方法。

}
</pre>
在AddJob时,将Job传入JobData中。

      

      

上面我们新增多个JobManager.cs类,类内只有2个粗略的AddJob方法

上边大家开始展览调用Test。
新建多少个窗体项目,并足够对LY.QuartzClass项指标引用。
增产四个Job类,继承自JobBase
<pre>
public class FirstJob : JobBase
{
public override void Run()
{
Console.WriteLine(DateTime.Now.ToString());
}
}
</pre>

  接下去讲解达成的思路

  接下去讲解实现的笔触

using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LY.QuartzClass
{
public class JobManage
{
IScheduler schedudler;
public JobManage()
{
schedudler = StdSchedulerFactory.GetDefaultScheduler();
schedudler.Start();
}
    public void AddJob<T>(int Second) where T : JobBase
    {

        JobBase jbobj = Activator.CreateInstance<T>();
        IDictionary<string, object> jbData = new Dictionary<string, object>();
        jbData.Add("name", jbobj);

        IJobDetail job1 = JobBuilder.Create<JobInstance>()
            .SetJobData(new JobDataMap(jbData)).Build();

        ITrigger trigger1 = TriggerBuilder.Create()
            .StartNow()
            .WithSimpleSchedule(x => x.WithIntervalInSeconds(Second)
            .RepeatForever()).Build();

        schedudler.ScheduleJob(job1, trigger1);

    }

   public void AddJob<T>(string rule) where T : JobBase
    {
        JobBase jbInstance = Activator.CreateInstance<T>();
        IDictionary<string, object> jbData = new Dictionary<string, object>();
        jbData.Add("name", jbInstance);

        IJobDetail job1 = JobBuilder.Create<JobInstance>()
            .SetJobData(new JobDataMap(jbData)).Build();

        ITrigger trigger1 = TriggerBuilder.Create()
            .StartNow()
            .WithCronSchedule(rule).Build();

        schedudler.ScheduleJob(job1, trigger1);
    }
}
}

<pre>
public class SecondJob : JobBase
{
public override void Run()
{
Console.WriteLine(DateTime.Now.ToString() + “:Hello”);
}
}
</pre>

  

  

 

<pre>
public class ThirdJob : JobBase
{
public override void Run()
{
Console.WriteLine(DateTime.Now.ToString() + “:CronTest”);
}
}
</pre>
在窗体中开始展览调用
<pre>
private void button1_Click(object sender, EventArgs e)
{
JobManage job = new JobManage();
job.AddJob<FirstJob>(3);
job.AddJob<SecondJob>(6);
job.AddJob<ThirdJob>(“0/5 0-58 9 * * ?”);
}
</pre>
结果如下:

  先定义3个类库,类库只包涵二个类,BaseJob ,里面唯有三个Run()方法

  先定义二个类库,类库只含有四个类,BaseJob ,里面唯有一个Run()方法

在AddJob时,将Job传入JobData中。

亚洲必赢官网 3

  之后我们兑现的每1个学业都以继续自那一个类,完成Run()方法即可(每一种作业都当做2个单独的类库,引用那么些只有四个类的类库)

  之后我们兑现的每贰个功课都以连续自那几个类,完结Run()方法即可(各类作业都看作几个单身的类库,引用那几个只有3个类的类库)

上面大家开始展览调用Test。
新建3个窗体项目,并丰富对LY.QuartzClass项目标引用。
亚洲必赢官网 ,增产四个Job类,继承自JobBase

image.png

  

  

public class FirstJob : JobBase
{
public override void Run()
{
Console.WriteLine(DateTime.Now.ToString());
}
}
public abstract class BaseJob:MarshalByRefObject,IDisposable
{
        public abstract void Run();
}
public abstract class BaseJob:MarshalByRefObject,IDisposable
{
        public abstract void Run();
}

 

  接下去建立大家的作业管理宗旨类库Job.Service nuget安装Quartz.NET

  接下去建立大家的功课管理为主类库Job.Service nuget安装Quartz.NET

public class SecondJob : JobBase
{
public override void Run()
{
Console.WriteLine(DateTime.Now.ToString() + ":Hello");
}
}

  然后新建类JobImplement.cs完结Quartz.NET的IJob接口

  然后新建类JobImplement.cs达成Quartz.NET的IJob接口

 

  那样大家就能够在其间通过大家和好写的课业调度容器获取到动态加载的Job音讯,并运维Job的run方法,来兑现动态调度了(作业调度容器里的课业怎么着装载进去的在小说前边讲解)

  那样大家就能够在内部通过大家协调写的课业调度容器获取到动态加载的Job音信,并运转Job的run方法,来落到实处动态调度了(作业调度容器里的学业怎样装载进去的在篇章后边讲解)

public class ThirdJob : JobBase
{
public override void Run()
{
Console.WriteLine(DateTime.Now.ToString() + ":CronTest");
}
}

   jobRuntimeInfo是我们友好定义的实体类,里面富含了BaseJob,AppDomain,JobInfo
八个新闻

   jobRuntimeInfo是大家同心合力定义的实体类,里面含有了BaseJob,AppDomain,JobInfo
八个音信

 

  JobInfo是作业在上传到作业动态调度框架时所需求填写的学业基本消息

  JobInfo是作业在上传到作业动态调度框架时所急需填写的课业基本音讯

在窗体中开始展览调用

    

    

private void button1_Click(object sender, EventArgs e)
{
JobManage job = new JobManage();
job.AddJob<FirstJob>(3);
job.AddJob<SecondJob>(6);
job.AddJob<ThirdJob>("0/5 0-58 9 * * ?");
}

  

  

 

public class JobImplement : IJob
    {
        public void Execute(IJobExecutionContext context)
        {
            try
            {
                long jobId = context.JobDetail.JobDataMap.GetLong("JobId");
                //从作业调度容器里查找,如果找到,则运行
                var jobRuntimeInfo =  JobPoolManager.Instance.Get(jobId);
try
                    {
                        jobRuntimeInfo.Job.TryRun();
                    }
                    catch (Exception ex)
                    {
                        //写日志,任务调用失败
                        ConnectionFactory.GetInstance<Provider.JobStateRepository>()
                            .Update(new Provider.Tables.JobState()
                            {
                                JobId = jobId,
                                RunState = (int) Provider.DirectiveType.Stop,
                                UpdateTime = DateTime.Now
                            });
                        Common.Logging.LogManager.GetLogger(this.GetType()).Error(ex.Message, ex);
                    }

            }
            catch (Exception ex)
            {
                Common.Logging.LogManager.GetLogger(this.GetType()).Error(ex.Message, ex);
                //调用的时候失败,写日志,这里错误,属于系统级错误,严重错误
            }
        }
    }
public class JobImplement : IJob
    {
        public void Execute(IJobExecutionContext context)
        {
            try
            {
                long jobId = context.JobDetail.JobDataMap.GetLong("JobId");
                //从作业调度容器里查找,如果找到,则运行
                var jobRuntimeInfo =  JobPoolManager.Instance.Get(jobId);
try
                    {
                        jobRuntimeInfo.Job.TryRun();
                    }
                    catch (Exception ex)
                    {
                        //写日志,任务调用失败
                        ConnectionFactory.GetInstance<Provider.JobStateRepository>()
                            .Update(new Provider.Tables.JobState()
                            {
                                JobId = jobId,
                                RunState = (int) Provider.DirectiveType.Stop,
                                UpdateTime = DateTime.Now
                            });
                        Common.Logging.LogManager.GetLogger(this.GetType()).Error(ex.Message, ex);
                    }

            }
            catch (Exception ex)
            {
                Common.Logging.LogManager.GetLogger(this.GetType()).Error(ex.Message, ex);
                //调用的时候失败,写日志,这里错误,属于系统级错误,严重错误
            }
        }
    }

结果如下:

 

 

 

  JobRuntimeInfo

  JobRuntimeInfo

 

  

  

亚洲必赢官网 4

public class JobRuntimeInfo
    {
        public AppDomain AppDomain;
        public BaseJob Job { get; set; }

        public JobInfo JobModel { get; set; }
    }
public class JobRuntimeInfo
    {
        public AppDomain AppDomain;
        public BaseJob Job { get; set; }

        public JobInfo JobModel { get; set; }
    }

image.png

  JobInfo

  JobInfo

public class JobInfo
    {
        public long JobId { get; set; }
        public string JobName { get; set; }public string TaskCron { get; set; }
        public string Namespace { get; set; }
        public string MainDllName { get; set; }
        public string Remark { get; set; }
        public string ZipFileName { get; set; }

        public string Version { get; set; }

        public DateTime? CreateTime { get; set; }
    }
public class JobInfo
    {
        public long JobId { get; set; }
        public string JobName { get; set; }public string TaskCron { get; set; }
        public string Namespace { get; set; }
        public string MainDllName { get; set; }
        public string Remark { get; set; }
        public string ZipFileName { get; set; }

        public string Version { get; set; }

        public DateTime? CreateTime { get; set; }
    }

 

 

   接下来大家来讲课这几个作业是何等实行的

   接下来大家来上课那几个作业是怎样进行的

  壹.透过一个上传页面把作业类库打包为zip也许rar上传出服务器,并填写Job运行的相干消息,添加到数据Curry

  1.通过一个上传页面把作业类库打包为zip可能rar上传出服务器,并填写Job运转的有关音讯,添加到数据Curry

  二.上传完毕之后发布一条广播新闻给全体的功课调度框架

  二.上传完毕今后发表一条广播新闻给持有的功课调度框架

  叁.功课调度框架接收到广播音讯,从数据库获取JobInfo,自动依照上传的时候填写的消息(见上面的JobInfo类的属性),自动解压,装载到AppDomain里

  三.功课调度框架接收到广播音信,从数据库获取JobInfo,自动根据上传的时候填写的音讯(见上边的JobInfo类的个性),自动解压,装载到AppDomain里

public class AppDomainLoader
    {
        /// <summary>
        /// 加载应用程序,获取相应实例
        /// </summary>
        /// <param name="dllPath"></param>
        /// <param name="classPath"></param>
        /// <param name="appDomain"></param>
        /// <returns></returns>
        public static BaseJob Load(string dllPath, string classPath, out AppDomain appDomain) where T : class
        {
            AppDomainSetup setup = new AppDomainSetup();
            if (System.IO.File.Exists($"{dllPath}.config"))
                setup.ConfigurationFile = $"{dllPath}.config";
            setup.ShadowCopyFiles = "true";
            setup.ApplicationBase = System.IO.Path.GetDirectoryName(dllPath);
            appDomain = AppDomain.CreateDomain(System.IO.Path.GetFileName(dllPath), null, setup);
            AppDomain.MonitoringIsEnabled = true;
            BaseJob obj = (BaseJob) appDomain.CreateInstanceFromAndUnwrap(dllPath, classPath);
            return obj;
        }

        /// <summary>
        /// 卸载应用程序
        /// </summary>
        /// <param name="appDomain"></param>
        public static void UnLoad(AppDomain appDomain)
        {
            AppDomain.Unload(appDomain);
            appDomain = null;
        }
    }
public class AppDomainLoader
    {
        /// <summary>
        /// 加载应用程序,获取相应实例
        /// </summary>
        /// <param name="dllPath"></param>
        /// <param name="classPath"></param>
        /// <param name="appDomain"></param>
        /// <returns></returns>
        public static BaseJob Load(string dllPath, string classPath, out AppDomain appDomain) where T : class
        {
            AppDomainSetup setup = new AppDomainSetup();
            if (System.IO.File.Exists($"{dllPath}.config"))
                setup.ConfigurationFile = $"{dllPath}.config";
            setup.ShadowCopyFiles = "true";
            setup.ApplicationBase = System.IO.Path.GetDirectoryName(dllPath);
            appDomain = AppDomain.CreateDomain(System.IO.Path.GetFileName(dllPath), null, setup);
            AppDomain.MonitoringIsEnabled = true;
            BaseJob obj = (BaseJob) appDomain.CreateInstanceFromAndUnwrap(dllPath, classPath);
            return obj;
        }

        /// <summary>
        /// 卸载应用程序
        /// </summary>
        /// <param name="appDomain"></param>
        public static void UnLoad(AppDomain appDomain)
        {
            AppDomain.Unload(appDomain);
            appDomain = null;
        }
    }

 

 

  4.因为作业都继承了BaseJob类,所以AppDomain里的入口程序就是JobInfo.Namespace,反射实例化之后强制转换为BaseJob,然后创制一个JobRuntime对象,添加到JobPoolManager里,JobPoolManager里维护有着的正在运行的Job

  四.因为作业都继承了BaseJob类,所以AppDomain里的输入程序正是JobInfo.Namespace,反射实例化之后强制转换为BaseJob,然后成立三个JobRuntime对象,添加到JobPoolManager里,JobPoolManager里维护有着的正在运维的Job

  伍.依照JobInfo.TaskCron(时间表明式)创制Trigger,创造八个JobImplement,并在Context里加几个JobId,保险在JobImplement的Run运转的时候能够从JobPoolManager里获取到Job的大旨音信,以及BaseJob的例子,并调用JobRuntime=>BaseJob=>Run()方法来运作实际上的功课

  5.基于JobInfo.TaskCron(时间表明式)成立Trigger,创设多少个JobImplement,并在Context里加多少个JobId,有限支撑在JobImplement的Run运营的时候能够从JobPoolManager里获取到Job的着力新闻,以及BaseJob的例子,并调用JobRuntime=>BaseJob=>Run()方法来运营实际上的功课

  

  

 public class JobPoolManager:IDisposable
    {
        private static ConcurrentDictionary<long, JobRuntimeInfo> JobRuntimePool =
            new ConcurrentDictionary<long, JobRuntimeInfo>();

        private static IScheduler _scheduler;
        private static JobPoolManager _jobPollManager;

        private JobPoolManager(){}

        static JobPoolManager()
        {
            _jobPollManager = new JobPoolManager();
            _scheduler = StdSchedulerFactory.GetDefaultScheduler();
            _scheduler.Start();
        }

        public static JobPoolManager Instance
        {
            get { return _jobPollManager; }

        }


        static object _lock=new object();
        public bool Add(long jobId, JobRuntimeInfo jobRuntimeInfo)
        {
            lock (_lock)
            {
                if (!JobRuntimePool.ContainsKey(jobId))
                {
                    if (JobRuntimePool.TryAdd(jobId, jobRuntimeInfo))
                    {
                        IDictionary<string, object> data = new Dictionary<string, object>()
                        {
                            ["JobId"]=jobId
                        };
                        IJobDetail jobDetail = JobBuilder.Create<JobImplement>()
                            .WithIdentity(jobRuntimeInfo.JobModel.JobName, jobRuntimeInfo.JobModel.Group)
                            .SetJobData(new JobDataMap(data))
                            .Build();
                        var tiggerBuilder = TriggerBuilder.Create()
                            .WithIdentity(jobRuntimeInfo.JobModel.JobName, jobRuntimeInfo.JobModel.Group);
                        if (string.IsNullOrWhiteSpace(jobRuntimeInfo.JobModel.TaskCron))
                        {
                            tiggerBuilder = tiggerBuilder.WithSimpleSchedule((simple) =>
                            {
                                simple.WithInterval(TimeSpan.FromSeconds(1));
                            });
                        }
                        else
                        {
                            tiggerBuilder = tiggerBuilder
                                .StartNow()
                                .WithCronSchedule(jobRuntimeInfo.JobModel.TaskCron);
                        }
                        var trigger = tiggerBuilder.Build();
                        _scheduler.ScheduleJob(jobDetail, trigger);
                        return true;
                    }
                }
                return false;
            }
        }

        public JobRuntimeInfo Get(long jobId)
        {
            if (!JobRuntimePool.ContainsKey(jobId))
            {
                return null;
            }
            lock (_lock)
            {
                if (JobRuntimePool.ContainsKey(jobId))
                {
                    JobRuntimeInfo jobRuntimeInfo = null;
                    JobRuntimePool.TryGetValue(jobId, out jobRuntimeInfo);
                    return jobRuntimeInfo;
                }
                return null;
            }
        }

        public bool Remove(long jobId)
        {
            lock (_lock)
            {
                if (JobRuntimePool.ContainsKey(jobId))
                {
                    JobRuntimeInfo jobRuntimeInfo = null;
                    JobRuntimePool.TryGetValue(jobId, out jobRuntimeInfo);
                    if (jobRuntimeInfo != null)
                    {
                        var tiggerKey = new TriggerKey(jobRuntimeInfo.JobModel.JobName,
                            jobRuntimeInfo.JobModel.Group);
                        _scheduler.PauseTrigger(tiggerKey);

                        _scheduler.UnscheduleJob(tiggerKey);

                        _scheduler.DeleteJob(new JobKey(jobRuntimeInfo.JobModel.JobName,
                            jobRuntimeInfo.JobModel.Group));

                        JobRuntimePool.TryRemove(jobId, out jobRuntimeInfo);

                        return true;
                    }
                }
                return false;
            }
        }

        public virtual void Dispose()
        {
            if (_scheduler != null && !_scheduler.IsShutdown)
            {
                foreach (var jobId in JobRuntimePool.Keys)
                {
                    var jobState = ConnectionFactory.GetInstance<Job.Provider.JobStateRepository>().Get(jobId);
                    if (jobState != null)
                    {
                        jobState.RunState = (int) DirectiveType.Stop;
                        jobState.UpdateTime = DateTime.Now;
                        ConnectionFactory.GetInstance<Job.Provider.JobStateRepository>().Update(jobState);
                    }
                }
                _scheduler.Shutdown();
            }
        }
    }
 public class JobPoolManager:IDisposable
    {
        private static ConcurrentDictionary<long, JobRuntimeInfo> JobRuntimePool =
            new ConcurrentDictionary<long, JobRuntimeInfo>();

        private static IScheduler _scheduler;
        private static JobPoolManager _jobPollManager;

        private JobPoolManager(){}

        static JobPoolManager()
        {
            _jobPollManager = new JobPoolManager();
            _scheduler = StdSchedulerFactory.GetDefaultScheduler();
            _scheduler.Start();
        }

        public static JobPoolManager Instance
        {
            get { return _jobPollManager; }

        }


        static object _lock=new object();
        public bool Add(long jobId, JobRuntimeInfo jobRuntimeInfo)
        {
            lock (_lock)
            {
                if (!JobRuntimePool.ContainsKey(jobId))
                {
                    if (JobRuntimePool.TryAdd(jobId, jobRuntimeInfo))
                    {
                        IDictionary<string, object> data = new Dictionary<string, object>()
                        {
                            ["JobId"]=jobId
                        };
                        IJobDetail jobDetail = JobBuilder.Create<JobImplement>()
                            .WithIdentity(jobRuntimeInfo.JobModel.JobName, jobRuntimeInfo.JobModel.Group)
                            .SetJobData(new JobDataMap(data))
                            .Build();
                        var tiggerBuilder = TriggerBuilder.Create()
                            .WithIdentity(jobRuntimeInfo.JobModel.JobName, jobRuntimeInfo.JobModel.Group);
                        if (string.IsNullOrWhiteSpace(jobRuntimeInfo.JobModel.TaskCron))
                        {
                            tiggerBuilder = tiggerBuilder.WithSimpleSchedule((simple) =>
                            {
                                simple.WithInterval(TimeSpan.FromSeconds(1));
                            });
                        }
                        else
                        {
                            tiggerBuilder = tiggerBuilder
                                .StartNow()
                                .WithCronSchedule(jobRuntimeInfo.JobModel.TaskCron);
                        }
                        var trigger = tiggerBuilder.Build();
                        _scheduler.ScheduleJob(jobDetail, trigger);
                        return true;
                    }
                }
                return false;
            }
        }

        public JobRuntimeInfo Get(long jobId)
        {
            if (!JobRuntimePool.ContainsKey(jobId))
            {
                return null;
            }
            lock (_lock)
            {
                if (JobRuntimePool.ContainsKey(jobId))
                {
                    JobRuntimeInfo jobRuntimeInfo = null;
                    JobRuntimePool.TryGetValue(jobId, out jobRuntimeInfo);
                    return jobRuntimeInfo;
                }
                return null;
            }
        }

        public bool Remove(long jobId)
        {
            lock (_lock)
            {
                if (JobRuntimePool.ContainsKey(jobId))
                {
                    JobRuntimeInfo jobRuntimeInfo = null;
                    JobRuntimePool.TryGetValue(jobId, out jobRuntimeInfo);
                    if (jobRuntimeInfo != null)
                    {
                        var tiggerKey = new TriggerKey(jobRuntimeInfo.JobModel.JobName,
                            jobRuntimeInfo.JobModel.Group);
                        _scheduler.PauseTrigger(tiggerKey);

                        _scheduler.UnscheduleJob(tiggerKey);

                        _scheduler.DeleteJob(new JobKey(jobRuntimeInfo.JobModel.JobName,
                            jobRuntimeInfo.JobModel.Group));

                        JobRuntimePool.TryRemove(jobId, out jobRuntimeInfo);

                        return true;
                    }
                }
                return false;
            }
        }

        public virtual void Dispose()
        {
            if (_scheduler != null && !_scheduler.IsShutdown)
            {
                foreach (var jobId in JobRuntimePool.Keys)
                {
                    var jobState = ConnectionFactory.GetInstance<Job.Provider.JobStateRepository>().Get(jobId);
                    if (jobState != null)
                    {
                        jobState.RunState = (int) DirectiveType.Stop;
                        jobState.UpdateTime = DateTime.Now;
                        ConnectionFactory.GetInstance<Job.Provider.JobStateRepository>().Update(jobState);
                    }
                }
                _scheduler.Shutdown();
            }
        }
    }

 

 

  

  

  然后我们除了做了1个web版的上传界面之外,还能做有所的job列表,用来做Start|Stop|Restart等,思路就是公布一条广播给全部的学业调度框架,作业调度框架依照广播音讯来展开学业的装载,运转,结束,卸载等操作。

  然后大家除了做了八个web版的上传界面之外,还足以做有所的job列表,用来做Start|Stop|Restart等,思路正是发表一条广播给全数的课业调度框架,作业调度框架依据广播新闻来举行学业的装载,运维,甘休,卸载等操作。

  至此,2个主干的动态作业调度框架就终止了。

  至此,三个基本的动态作业调度框架就停止了。

 

 

 

 

 

 

  

  

 

 

网站地图xml地图