任务调度类似于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配置信息加进来,以减少程序的松耦性。