基于Quartz.Net 的软件热插拔

需求 平台可以管理所有的定时作业 只要上传dll ,然后不用你管 。 每个dll 就是一个任务

任务一

 

namespace CXY_One
{
    [PersistJobDataAfterExecution] 
    [DisallowConcurrentExecution]
    public class Task_One : AbstractIjob, IJob
    {
        public Task Execute(IJobExecutionContext context)
        {

            return Task.Run(()=> {

                Console.WriteLine("*****美橙科技*1111111111111111111111**********");
            
            });

        }

        public override JobModel InitJobModel()
        {
            return new JobModel("deflaut", "deflautgroup", "deflaut", "3/5 * * * * ?", new Hashtable());
        }
    }
}

任务2

namespace CXY_Two
{
    [PersistJobDataAfterExecution] 
    [DisallowConcurrentExecution] 
    public class Task_Two : AbstractIjob, IJob
    {
        public Task Execute(IJobExecutionContext context)
        {
            var ht = context.JobDetail.JobDataMap.Get("data") as Hashtable;

        

            return Task.Run(() =>
            {
                foreach (var item in ht)
                {
                    Console.WriteLine($"item:{item.ToString()}2222222222222222222222222222");
              
                }
             
            });
        }

        public override JobModel InitJobModel()
        {
            return new JobModel("abc", "deflautgroup2", "deflaut2", "3/10 * * * * ?", new Hashtable() { { "key1", "你好" }, { "key2", "你好帅" } });
        }
    }
}

 

核心代码
namespace CNDNS.WorkServices
{
    public class JobManage
    {
        public async Task RunAsync()
        {
            ///任务放到一个集合中
            List<AbstractIjob> ijobs = new List<AbstractIjob>();
            ///没有界面暂时写死路径
            var path = @"D:\345\";
            // 策略 读取cxy 的前缀的dll
         string[] fileInfos = Directory.GetFiles(path).Where(f => f.Contains("CXY_")).ToArray();
//流方式 读取dell
            var assemblyLoadContext = new AssemblyLoadContext(Guid.NewGuid().ToString("N"), true);

            Dictionary<string, AbstractIjob> fileInfolist = new Dictionary<string, AbstractIjob>();
            foreach (var item in fileInfos)
            {
                AbstractIjob abstractIjob;

                using (var fs = new FileStream(item, FileMode.Open, FileAccess.Read))
                {

                    var assembly = assemblyLoadContext.LoadFromStream(fs);

                    Type type = assembly.GetExportedTypes().Where(f => f.GetInterfaces().Contains(typeof(IJob))).FirstOrDefault();
                //反射创建对象
                    abstractIjob = Activator.CreateInstance(type) as AbstractIjob;
                }
                FileInfo fileInfo = new FileInfo(item);
                abstractIjob.FileInfoLastTime = fileInfo.LastWriteTime;
                fileInfolist.Add(fileInfo.Name, abstractIjob);
                if (!SchedulerCenter.dllexe.ContainsKey(fileInfo.Name))
                {

                    SchedulerCenter.AddJob(abstractIjob);
                    SchedulerCenter.dllexe[fileInfo.Name] = abstractIjob;
                }
                if (SchedulerCenter.dllexe.ContainsKey(fileInfo.Name) && fileInfo.LastWriteTime > SchedulerCenter.dllexe[fileInfo.Name].FileInfoLastTime)
                {
                    // 先删 
                    SchedulerCenter.RomverJob(abstractIjob);
                    SchedulerCenter.dllexe.Remove(fileInfo.Name);

                    // 再加
                    SchedulerCenter.AddJob(abstractIjob);
                    SchedulerCenter.dllexe[fileInfo.Name] = abstractIjob;
                }

            }
            var dllkeys = SchedulerCenter.dllexe.Keys.ToArray();
         
            for (int i = dllkeys.Length - 1; i >= 0; i--)
            {
             
                if (!fileInfolist.Keys.Contains(dllkeys[i]))
                {
                    SchedulerCenter.RomverJob(SchedulerCenter.dllexe[dllkeys[i]]);
                    SchedulerCenter.dllexe.Remove(dllkeys[i]);
                }
            }
        }




    }
}

 


截图

 

 

 

 

posted @ 2021-11-05 18:08  非著名架构师  阅读(145)  评论(0编辑  收藏  举报