定时任务 Wpf.Quartz.Demo.5 (升级版)

老规矩:先把全部源码上传,见本文底部。

相对于Demo3的区别,就是能自动加载继承了IJob的任务,任务主体程序分离。

在exe执行文件的同级下建一个MyJobs的文件夹,每次会自动扫描该文件夹下的Job,添加到系统中来。

 

举例如下:现在有两个在系统中的任务。

复制一个编译好的Job dll文件放在MyJobs  按下工具菜单栏中的扫描,会有一个新增的任务出现。(是不影响其它正在执行的任务哦)

 

好了,图贴完,现在将下面几个技术要点。

1. 动态加载dll

IRun getRun;

        public void NewRun<T>() where T:IJob
        {
            getRun = new SimpleRunner<T>();
        }
try
            {
                string dir = System.AppDomain.CurrentDomain.BaseDirectory + "MyJobs";
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }

                DirectoryInfo TheFolder = new DirectoryInfo(dir);
                foreach (FileInfo fi in TheFolder.GetFiles())//遍历文件夹下所有文件
                {
                    string extension = Path.GetExtension(fi.FullName);//扩展名 ".aspx"
                    if (extension == ".dll")
                    {
                        #region 获取jobs
                        string path = fi.FullName;//dir + "\\Wpf.Quart.MyJobs.dll";
                        Assembly asm = Assembly.LoadFile(path);

                        //Assembly asm = Assembly.GetExecutingAssembly();
                        Type[] types = asm.GetTypes();

                        foreach (Type t in types)
                        {
                            if (new ArrayList(t.GetInterfaces()).Contains(typeof(IJob)))
                            {
                                IJob job = ObjectUtils.InstantiateType<IJob>(t);
                                if (job != null)
                                {
                                    MethodInfo mi = this.GetType().GetMethod("NewRun").MakeGenericMethod(new Type[] { t });
                                    mi.Invoke(this, null);

                                    IRun run = getRun;
                                    if (TaskRuns.Where(p => p.GetType() == run.GetType()).Count() > 0)
                                    {
                                        continue;
                                    }


                                    if (run != null)
                                    {
                                        if (localRuns != null)
                                        {
                                            var localRun = localRuns.Where(p => p.Name == run.Name).FirstOrDefault();
                                            if (localRun != null)
                                            {
                                                CopyHelper.LeftCopyRight(run, localRun);
                                            }
                                        }
                                        if (run.TriggerState != TriggerState.Normal || run.Mode == Mode.Hand)
                                        {
                                            run.TriggerState = TriggerState.None;
                                        }
                                        run.CronSecondSet.Init();
                                        run.CronMinuteSet.Init();
                                        run.CronHourSet.Init();
                                        run.CronDaySet.Init();
                                        run.CronMonthSet.Init();
                                        run.CronWeekSet.Init();
                                        run.CronYearSet.Init();
                                        run.LogOut = this.LogOut;
                                        run.IsEdit = false;
                                        TaskRuns.Add(run);
                                    }
                                }
                            }
                        }
                        #endregion
                    }
                }
            }
            catch (Exception ex)
            {
                log.Fatal(ex);
            }

二.分离出几个关键的接口放到另一个库中,需要实现的任务加载那个dll库就行。主要用来显示的,如果你的任务不用显示,那么可以不需要这几个接口,直接继承IJob就行

public class JobHelper
    {
        public static IJobRun GetRun(IJobExecutionContext context)
        {
            JobDataMap data = context.JobDetail.JobDataMap;

            IJobRun Run = data.Get("Runner") as IJobRun;
            if (Run != null)
            {
                Run.GetNextRunTimes();
            }
            return Run;
        }
    }
JobHelper
 public interface IJobRun
    {
        string CronExpression { get; set; }
        TriggerState TriggerState { get; set; }
        string SettingStr { get; set; }
        DateTime? StartTime { get; set; }
        DateTime? EndTime { get; set; }
        DateTime? NextRunTime { get; }
        DateTime[] NextRunTimes { get; set; }
        void GetNextRunTimes();
        void Info(string message);
        void DEBUG(string message);
        void ERROR(string message);
        void FATAL(string message);
        void WARN(string message);
    }
IJobRun

三.具体任务的简单例子

public class MyHelloJobEx : IJob
    {
        public async Task Execute(IJobExecutionContext context)
        {
            await Console.Out.WriteLineAsync("HelloJob is executing.");
            var Run = JobHelper.GetRun(context);
            if (Run != null)
            {
                Run.Info("HelloJob is executing.");
            }
        }
    }

//JobHelper主要是来界面显示日志,获取下次任务执行时间。不需要,可以不用。
View Code

最后补充一下,水平不足,有点乱,抱歉。

 

源码下载地址:链接:https://pan.baidu.com/s/15UD5oMia8REnYVtJE4_xHA
提取码:pexq

 

posted @ 2019-03-19 15:31  竹天笑  阅读(1623)  评论(6编辑  收藏  举报