定時任務 Wpf.Quartz.Demo.5 (升級版)

来源:https://www.cnblogs.com/akwkevin/archive/2019/03/19/10557749.html
-Advertisement-
Play Games

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

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 第1節. 關鍵字 馳騁工作流引擎 流程快速開發平臺 workflow ccflow jflow 第2節. 流程中途結束設計 一條流程走到一定的步驟後,當前的節點有權利停止該流程向下運動,但是他不能把流程刪除掉,該數據仍然需要保存起來,這種操作叫結束流程。 結束流程與刪除流程不同的是: 1,結束流程數 ...
  • 前言 我們學習任何一個新框架時,肯定都需要學習它的子頁面用法,因為子頁面是封裝公共內容最好的容器。 在Xamarin裡子頁面為Fragment,翻譯過來是片段的意思。 Fragment 下麵我們來學習Fragment的用法。 首先創建一個類MenuFragment繼承Fragment;然後重寫他的O ...
  • 使用反射和動態生成代碼兩種方式(Reflect和Emit) 反射將DataTable轉為List方法 1 public static List<T> ToListByReflect<T>(this DataTable dt) where T : new() 2 { 3 List<T> ts = ne ...
  • 右鍵解決方案,添加引用--> System.Configuration.dll 在exe.config 中添加數據 讀取添加的配置數據 ...
  • 問題描述: 項目在本地運行不報錯,上傳到 GitHub 之後,再 clone 到本地,執行: npm install 安裝完成之後再執行: npm run dev 這時報錯 Error: No PostCSS Config found in... 本以為是 GitHub 上傳的問題,後開又試了兩回, ...
  • 很多企業和個人的網站上線後,一直不被百度、搜狗、谷歌等搜索引擎收錄網頁,但仔細查看網站,網站已經有很多的文章內容了,即使再保持頻繁的更新,網站依舊未被這些搜索引擎收錄頁面,這對於企業網站或者個人網站來說是不好的,相當於別人無法通過搜索查找到你網站的信息。在這個環節可能是你的網站SEO方面以及網站運維 ...
  • 這周其實突然感覺焦慮有點蔓延。主要是隨便上招聘網站、培訓網站、開發類新聞網,.Net的身影已經越來越少了,並不一定說是要貶低.net,而是這些年他的職業前景確實不太光鮮。一線主流企業的核心場景都不用.net的,或者只是被當成備胎,要不是這兩年微軟的開源政策有所改觀,市場有點動靜,否則連備胎都當不成。 ...
  • 簡介:本文是一個簡單的demo用於展示利用StackExchange.Redis和Log4Net構建日誌隊列,為高併發日誌處理提供一些思路。 0、先下載安裝Redis服務,然後再服務列表裡啟動服務(Redis的預設埠是6379,貌似還有一個故事)(https://github.com/Micros ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...