任務調度類似於sqlserver中的作業,即按周期性執行某個程序,代碼段,或者某種服務,在JAVA環境中出現了Quartz,它可以簡單的實現任務的調試,而像lucene一樣,它會有對於的.net版本,Quartz.net,今天我們來做一個簡單的實驗,其時很簡單的實驗:
環境:.net4.0+mvc3
功能:每1分鍾去向一個文件里寫日志(當然,如果你要調用某個服務,只要讓它實現IJob接口即可。
所需要的程序集
首先在WEB.Config的configuration節點里做一些必要的配置
1 <configSections> 2 <section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089"/> 3 <sectionGroup name="common"> 4 <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging"/> 5 </sectionGroup> 6 </configSections> 7 <common> 8 <logging> 9 <factoryAdapter type="Common.Logging.Simple.ConsoleOutLoggerFactoryAdapter, Common.Logging"> 10 <arg key="showLogName" value="true"/> 11 <arg key="showDataTime" value="true"/> 12 <arg key="level" value="INFO"/> 13 <arg key="dateTimeFormat" value="HH:mm:ss:fff"/> 14 </factoryAdapter> 15 </logging> 16 </common> 17 18 <quartz> 19 <add key="quartz.scheduler.instanceName" value="ExampleDefaultQuartzScheduler"/> 20 21 <add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz"/> 22 <add key="quartz.threadPool.threadCount" value="10"/> 23 <add key="quartz.threadPool.threadPriority" value="2"/> 24 25 <add key="quartz.jobStore.misfireThreshold" value="60000"/> 26 <add key="quartz.jobStore.type" value="Quartz.Simpl.RAMJobStore, Quartz"/> 27 </quartz>
在global.asax.cs里添加調用和取消調用的代碼
1 protected void Application_Start() 2 { 3 WriteLogScheduler.Instance.Start(); 4 } 5 6 protected void Application_End(object sender, EventArgs e) 7 { 8 WriteLogScheduler.Instance.Stop(); 9 }
所要調用的任務,它需要實現IJob接口
1 /// <summary> 2 /// 要調度的功能模塊 3 /// </summary> 4 public class WriteLogJob : IJob 5 { 6 public void Execute(IJobExecutionContext context) 7 { 8 string fileLogPath = AppDomain.CurrentDomain.BaseDirectory; 9 string fileLogName = "TestQuartz_" + DateTime.Now.ToLongDateString() + "_log.txt"; 10 FileInfo finfo = new FileInfo(fileLogPath + fileLogName); 11 using (FileStream fs = finfo.OpenWrite()) 12 { 13 //根據上面創建的文件流創建寫數據流 14 StreamWriter strwriter = new StreamWriter(fs); 15 //設置寫數據流的起始位置為文件流的末尾 16 strwriter.BaseStream.Seek(0, SeekOrigin.End); 17 //寫入相關記錄信息 18 strwriter.WriteLine("發生時間: " + DateTime.Now.ToString()); 19 strwriter.WriteLine("---------------------------------------------"); 20 strwriter.WriteLine(); 21 //清空緩沖區內容,並把緩沖區內容寫入基礎流 22 strwriter.Flush(); 23 strwriter.Close(); 24 fs.Close(); 25 } 26 } 27 28 }
添加調用任務的代碼,Quartz服務核心代碼
1 public class WriteLogScheduler 2 { 3 4 static ISchedulerFactory _sf = new StdSchedulerFactory(); 5 static IScheduler _sched = _sf.GetScheduler(); 6 static WriteLogScheduler _instance = null; 7 static object lockObj = new object(); 8 9 /// <summary> 10 /// 線程安全的單例對象 11 /// </summary> 12 public static WriteLogScheduler Instance 13 { 14 get 15 { 16 if (_instance == null) 17 { 18 lock (lockObj) 19 { 20 if (_instance == null) 21 { 22 _instance = new WriteLogScheduler(); 23 } 24 } 25 } 26 return _instance; 27 } 28 } 29 30 public void Start() 31 { 32 ILog log = LogManager.GetLogger(typeof(WriteLogScheduler)); 33 DateTimeOffset runTime = DateBuilder.EvenMinuteDate(DateTimeOffset.UtcNow); 34 // define the job and tie it to our HelloJob class 35 IJobDetail job = JobBuilder.Create<WriteLogJob>() 36 .WithIdentity("job1", "group1") 37 .Build(); 38 // Trigger the job to run on the next round minute 39 ITrigger trigger = TriggerBuilder.Create() 40 .WithIdentity("trigger1", "group1") 41 .StartAt(runTime) 42 .Build(); 43 // Tell quartz to schedule the job using our trigger 44 _sched.ScheduleJob(job, trigger); 45 _sched.Start(); 46 } 47 public void Stop() 48 { 49 _sched.Shutdown(true); 50 } 51 52 }
運行程序,即可看到結果了,下一講,我將把XML配置信息加進來,以減少程序的松耦性。