定时任务 Wpf.Quartz.Demo.5 (升级版)
程序员文章站
2022-04-28 13:18:16
老规矩:先把全部源码上传,见本文底部。 相对于Demo3的区别,就是能自动加载继承了IJob的任务,任务主体程序分离。 在exe执行文件的同级下建一个MyJobs的文件夹,每次会自动扫描该文件夹下的Job,添加到系统中来。 举例如下:现在有两个在系统中的任务。 复制一个编译好的Job dll文件放在 ......
老规矩:先把全部源码上传,见本文底部。
相对于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; } }
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); }
三.具体任务的简单例子
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主要是来界面显示日志,获取下次任务执行时间。不需要,可以不用。
最后补充一下,水平不足,有点乱,抱歉。
源码下载地址:链接:https://pan.baidu.com/s/15ud5omia8renyvtje4_xha
提取码:pexq
上一篇: JAVA基础-操作符篇
下一篇: 咬住尾巴可以让脸变得更清晰