老規矩:先把全部源碼上傳,見本文底部。 相對於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; } }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