首页 > 代码库 > windows 服务实现定时任务调度(Quartz.Net)

windows 服务实现定时任务调度(Quartz.Net)

我们通常在一些情况下需要软件具有一个自动执行某些任务的功能,但是又不希望直接启动软件,或者每次都要手动的来启动软件,这时我们可可以考虑到windows服务了。

首先创建一个windows服务项目(详细信息请参阅:C#创建Windows Service(Windows 服务)基础教程

    

在创建好的项目中点击“单击此处切换到代码视图”切换到代码

我们主要关注一下两个方法:

  • OnStart – 控制服务启动
  • OnStop – 控制服务停止

  例:

 1     public partial class Service1 : ServiceBase 2     { 3         public Service1() 4         { 5             InitializeComponent(); 6         } 7  8         protected override void OnStart(string[] args) 9         {10             //todo:这里是服务启动所执行的代码11         }12 13         protected override void OnStop()14         {15             //todo:这里是服务停止所执行的代码16         }17     }
View Code

 下面我们可以写一个定时任务的功能了:

  

 1      private void StartDoSomething() 2         { 3             System.Timers.Timer timer = new System.Timers.Timer(10000); //间隔10秒 4             timer.AutoReset = true; 5             timer.Enabled = false;  //执行一次 6             timer.Elapsed += new ElapsedEventHandler(ExecutionCode); 7             timer.Start(); 8         } 9 10         private void ExecutionCode(object source, System.Timers.ElapsedEventArgs e)11         {12             string dtNow = DateTime.Now.ToString("HH:mm");13             if (dtNow == "12:00")14             {15                 File.WriteAllText("D:/ExecutionService.txt", "服务执行了一次任务", Encoding.UTF8);16             }17         }

然后在OnStart的方法中调用上面的StartDoSomething的方法

1         protected override void OnStart(string[] args)2         {3             StartDoSomething();4         }    

以上就可以算是一个简单的定时执行任务的windows服务了,可是在这里并不完善,在服务中使用Timer并不好,所以我们可以使用Quartz.Net来实现任务调度功能。

 

首先来介绍一下Quartz.Net这个框架:

  简介:Quartz.Net是一个开源的任务调度框架,非常强大,能够通过简单的配置帮助我们定时具体的操作。相对于我们用的线程里面while(true)然后sleep来执行某个操作,应该算的上是高端,大气,上档次了。目前最新版本是2.2,新的版本里面有些方法名发生了变化,从之前的版本用过来的人应该会有体会.这里我使用最常用,也是最稳定的方式--Windows服务里面使用Quartz.net,并且使用配置的方式来设置触发器。(以上内容摘自网络)

  简单的理解就是它能够帮我们定时的做事,相当于闹钟能够叫我们起床一样。

  目前最新的版本是Quartz.NET 2.2.3 大家可以在这里下载

 

  现在我们需要在刚刚创建的服务项目中引用如下文件:

    

  在配置文件中写好自己的配置(本例子演示定时访问指定网站)

 1 <?xml version="1.0"?> 2 <configuration> 3   <configSections> 4     <sectionGroup name="JobList"> 5       <section name="Job" type="MyService1101.MyConfigHandler,MyService1101"/> 6     </sectionGroup> 7   </configSections> 8   <startup> 9     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />10   </startup>11   <JobList>12     <Job>   <!--这里是一个任务节点-->13       <add key="Url" value="http://www.baidu.com" />  <!--需要访问的Url-->14       <add key="Hour" value="10" />   <!--开始时间小时,注意:这里的小时为0-23,如果是1点的话就是1,而不是01-->15       <add key="Minute" value="30"/>    <!--开始时间分钟,注意:同上0-59-->16     </Job>17   </JobList>18 </configuration>
View Code

 

  新建一个MyConfigHandler.cs类来读取自定义配置节点

 1 public class MyConfigHandler : IConfigurationSectionHandler 2     { 3         public MyConfigHandler() 4         { 5         } 6  7         public object Create(object parent, object configContext, System.Xml.XmlNode section) 8         { 9             NameValueCollection configs;10             NameValueSectionHandler baseHandler = new NameValueSectionHandler();11             configs = (NameValueCollection)baseHandler.Create(parent, configContext, section);12             return configs;13         }14     }
View Code

 

  然后新建一个SystemScheduler类来创建调度程序

 1     public class SystemScheduler 2     { 3         private SystemScheduler() 4         { 5         } 6  7         public static SystemScheduler CreateInstance() 8         { 9             return new SystemScheduler();10         }11 12         private IScheduler _scheduler;13 14         public void StartScheduler()15         {16             //这里读取配置文件中的任务开始时间17             int hour = int.Parse(((NameValueCollection)ConfigurationSettings.GetConfig("JobList/Job"))["Hour"]);18             int minute = int.Parse(((NameValueCollection)ConfigurationSettings.GetConfig("JobList/Job"))["Minute"]);19 20             ISchedulerFactory schedulerFactory = new StdSchedulerFactory();//内存调度21             _scheduler = schedulerFactory.GetScheduler();22 23             //创建一个Job来执行特定的任务24             IJobDetail synchronousData = http://www.mamicode.com/new JobDetailImpl("SynchronousData", typeof(SynchronousData));25             //创建并定义触发器的规则(每天执行一次时间为:时:分)26             ITrigger trigger =27                 TriggerBuilder.Create()28                     .WithDailyTimeIntervalSchedule(29                         a => a.WithIntervalInHours(24).OnEveryDay().StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(hour, minute))).Build();30             //将创建好的任务和触发规则加入到Quartz中31             _scheduler.ScheduleJob(synchronousData, trigger);32             //开始33             _scheduler.Start();34         }35 36         public void StopScheduler()37         {38             _scheduler.Shutdown();39         }40     }
View Code

 

  新建一个SynchronousData类,让其实现IJob接口来实现SystemScheduler中自定义的任务

 1     public class SynchronousData : IJob 2     { 3         public void Execute(IJobExecutionContext context) 4            { 5             string Url = ((NameValueCollection)ConfigurationSettings.GetConfig("JobList/Job"))["Url"]; 6             WebClient wc = new WebClient(); 7             WebRequest wr = WebRequest.Create(new Uri(Url)); 8             using (StreamWriter sw = File.AppendText(@"d:\SchedulerService.txt")) 9             {10                 sw.WriteLine("------------------" + "MyService服务在:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "     执行了一次任务" + "------------------");11                 sw.Flush();12             }13         }14     }
View Code

 

  最后在OnStart中添加对这个调度程序的应用

1         protected override void OnStart(string[] args)2         {3             SystemScheduler _systemScheduler = SystemScheduler.CreateInstance();4             _systemScheduler.StartScheduler();5         }   

 

  程序生成后我们可以通过指令安装它

  安装完成后在服务中会有一个新的服务项

  

  程序运行过后会在D:盘生成一个SchedulerService.txt文件

  

 

  本程序源码:下载