工做中須要作個天天定時發郵件的功能,瞭解以後知道java裏有作定時任務比較容易的方法,就是Quartz,在C#裏叫Quartz.Net。html
在寫代碼以前須要引用幾個dll文件,分別是C5.dll、Common.Logging.dll和Quartz.dll;還有一個QuartzManager.cs文件,直接複製到項目中java
QuartzManager.cs多線程
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Quartz; using Quartz.Impl; using Quartz.Impl.Triggers; namespace Quartz { public static class QuartzManager { private static ISchedulerFactory sf = null; private static IScheduler sched = null; static QuartzManager() { sf = new StdSchedulerFactory(); sched = sf.GetScheduler(); sched.Start(); } /// <summary> /// 添加Job 而且以定點的形式運行 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="JobName"></param> /// <param name="CronTime"></param> /// <param name="jobDataMap"></param> /// <returns></returns> public static DateTimeOffset AddJob<T>(string JobName, string CronTime, string jobData) where T : IJob { IJobDetail jobCheck = JobBuilder.Create<T>().WithIdentity(JobName, JobName + "_Group").UsingJobData("jobData", jobData).Build(); ICronTrigger CronTrigger = new CronTriggerImpl(JobName + "_CronTrigger", JobName + "_TriggerGroup", CronTime); return sched.ScheduleJob(jobCheck, CronTrigger); } /// <summary> /// 添加Job 而且以定點的形式運行 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="JobName"></param> /// <param name="CronTime"></param> /// <returns></returns> public static DateTimeOffset AddJob<T>(string JobName, string CronTime) where T : IJob { return AddJob<T>(JobName, CronTime, null); } /// <summary> /// 添加Job 而且以週期的形式運行 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="JobName"></param> /// <param name="SimpleTime">毫秒數</param> /// <returns></returns> public static DateTimeOffset AddJob<T>(string JobName, int SimpleTime) where T : IJob { return AddJob<T>(JobName, DateTime.UtcNow.AddMilliseconds(1), TimeSpan.FromMilliseconds(SimpleTime)); } /// <summary> /// 添加Job 而且以週期的形式運行 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="JobName"></param> /// <param name="SimpleTime">毫秒數</param> /// <returns></returns> public static DateTimeOffset AddJob<T>(string JobName, DateTimeOffset StartTime, int SimpleTime) where T : IJob { return AddJob<T>(JobName, StartTime, TimeSpan.FromMilliseconds(SimpleTime)); } /// <summary> /// 添加Job 而且以週期的形式運行 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="JobName"></param> /// <param name="SimpleTime"></param> /// <returns></returns> public static DateTimeOffset AddJob<T>(string JobName, DateTimeOffset StartTime, TimeSpan SimpleTime) where T : IJob { return AddJob<T>(JobName, StartTime, SimpleTime, new Dictionary<string, object>()); } /// <summary> /// 添加Job 而且以週期的形式運行 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="JobName"></param> /// <param name="StartTime"></param> /// <param name="SimpleTime">毫秒數</param> /// <param name="jobDataMap"></param> /// <returns></returns> public static DateTimeOffset AddJob<T>(string JobName, DateTimeOffset StartTime, int SimpleTime, string MapKey, object MapValue) where T : IJob { Dictionary<string, object> map = new Dictionary<string, object>(); map.Add(MapKey, MapValue); return AddJob<T>(JobName, StartTime, TimeSpan.FromMilliseconds(SimpleTime), map); } /// <summary> /// 添加Job 而且以週期的形式運行 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="JobName"></param> /// <param name="StartTime"></param> /// <param name="SimpleTime"></param> /// <param name="jobDataMap"></param> /// <returns></returns> public static DateTimeOffset AddJob<T>(string JobName, DateTimeOffset StartTime, TimeSpan SimpleTime, Dictionary<string, object> map) where T : IJob { IJobDetail jobCheck = JobBuilder.Create<T>().WithIdentity(JobName, JobName + "_Group").Build(); jobCheck.JobDataMap.PutAll(map); ISimpleTrigger triggerCheck = new SimpleTriggerImpl(JobName + "_SimpleTrigger", JobName + "_TriggerGroup", StartTime, null, SimpleTriggerImpl.RepeatIndefinitely, SimpleTime); return sched.ScheduleJob(jobCheck, triggerCheck); } /// <summary> /// 修改觸發器時間,須要job名,以及修改結果 /// CronTriggerImpl類型觸發器 /// </summary> public static void UpdateTime(string jobName, string CronTime) { TriggerKey TKey = new TriggerKey(jobName + "_CronTrigger", jobName + "_TriggerGroup"); CronTriggerImpl cti = sched.GetTrigger(TKey) as CronTriggerImpl; cti.CronExpression = new CronExpression(CronTime); sched.RescheduleJob(TKey, cti); } /// <summary> /// 修改觸發器時間,須要job名,以及修改結果 /// SimpleTriggerImpl類型觸發器 /// </summary> /// <param name="jobName"></param> /// <param name="SimpleTime">分鐘數</param> public static void UpdateTime(string jobName, int SimpleTime) { UpdateTime(jobName, TimeSpan.FromMinutes(SimpleTime)); } /// <summary> /// 修改觸發器時間,須要job名,以及修改結果 /// SimpleTriggerImpl類型觸發器 /// </summary> public static void UpdateTime(string jobName, TimeSpan SimpleTime) { TriggerKey TKey = new TriggerKey(jobName + "_SimpleTrigger", jobName + "_TriggerGroup"); SimpleTriggerImpl sti = sched.GetTrigger(TKey) as SimpleTriggerImpl; sti.RepeatInterval = SimpleTime; sched.RescheduleJob(TKey, sti); } /// <summary> /// 暫停全部Job /// 暫停功能Quartz提供有不少,之後可擴充 /// </summary> public static void PauseAll() { sched.PauseAll(); } /// <summary> /// 恢復全部Job /// 恢復功能Quartz提供有不少,之後可擴充 /// </summary> public static void ResumeAll() { sched.ResumeAll(); } /// <summary> /// 刪除Job /// 刪除功能Quartz提供有不少,之後可擴充 /// </summary> /// <param name="JobName"></param> public static void DeleteJob(string JobName) { JobKey jk = new JobKey(JobName, JobName + "_Group"); sched.DeleteJob(jk); } /// <summary> /// 卸載定時器 /// </summary> /// <param name="waitForJobsToComplete">是否等待job執行完成</param> public static void Shutdown(bool waitForJobsToComplete) { sched.Shutdown(waitForJobsToComplete); } } }
窗體界面上只有一個Button按鈕,點擊以後將當前Windows窗體關閉,而個人定時任務就是實現這個關閉。學習
.closeForm();關閉窗體方法在另寫的一個stopjob.cs類文件調用 這個類須要繼承IJobui
using Quartz; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace winform狀態欄 { [PersistJobDataAfterExecution] [DisallowConcurrentExecution] public class stopjob : IJob { public void Execute(IJobExecutionContext context) { Program.form.closeForm(); } } }
上面代碼中,Program.form並非開始建立的那個窗體,而是在Program類文件中建立的靜態Form。爲何另建立一個靜態Form?涉及到子線程關閉主線程問題this
using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace winform狀態欄 { static class Program { public static Form1 form; /// <summary> /// 應用程序的主入口點。 /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); form = new Form1(); Application.Run(form); } } }
Form.cs文件裏引用Quartz(using Quartz;)spa
而後是關閉按鈕(Button)的事件線程
using Quartz; using System; using System.Text.RegularExpressions; using System.Windows.Forms; namespace winform狀態欄 { public partial class Form1 : Form { public Form1() { InitializeComponent(); }
private void button_close(object sender, EventArgs e) { //cron表達式 參考 http://www.cnblogs.com/sunjie9606/archive/2012/03/15/2397626.html QuartzManager.AddJob<stopjob>("每隔5秒", "*/5 * * * * ?");//每隔5秒執行一次這個方法 } private delegate void CloseForm();//設計到多線程,子線程去控制主線程的控件,InvokeRequired值爲true,用到定義委託,使得這個控制行爲成爲主線程的行爲 public void closeForm() { if (this.InvokeRequired) { this.BeginInvoke(new CloseForm(closeForm)); } else { this.Close(); } } } }
關於執行stopjob的時間,我這裏是用的每隔5秒執行一次,具體的解釋在另外一位博主那裏有介紹 設計
http://www.cnblogs.com/sunjie9606/archive/2012/03/15/2397626.html
其中C5.dll、Common.Logging.dll、Quartz.dll文件的連接http://pan.baidu.com/s/1hsBn1Bm(若是失效聯繫博主)code
我學習Quartz.Net時用的是winform,你們能夠試試別的,這樣關於線程的問題應該就能夠避免,這也是我沒有想到的問題