写在前面
这几天在弄一个项目,需要定时抓取一些数据,当时也想直接用timer算了。因为之前也弄过这样的项目,但是一想,已经用过了,再去使用同一种思路,未免太乏味了。就换了一种新玩法。这里将之前看到的一篇文章中提出的一个思路,在这个项目中实践了一下,发现乐在其中。
Quarzt.net
这篇文章,给了一种好玩的方式,并且自己也实践了一下,而且也确确实实在项目中用到了。
简单一个demo,先熟悉如何使用Quartz.NET
关于如何windows service的内容,这里不再赘述,一搜一大堆。
首先引入lib中的dll。
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Diagnostics; 6 using System.Linq; 7 using System.ServiceProcess; 8 using System.Text; 9 using System.Threading.Tasks;10 using Quartz;11 using Quartz.Job;12 using Common.Logging;13 using Quartz.Impl;14 using Statistics.WindowService.JobManager;15 using System.Configuration;16 namespace Statistics.WindowService17 {18 ///19 /// 数据同步windows服务20 /// 21 public partial class SyncDataService : ServiceBase22 {23 private readonly ILog logger;24 private IScheduler scheduler;25 //时间间隔26 private readonly string StrCron = ConfigurationManager.AppSettings["cron"] == null ? "* 10 * * * ?" : ConfigurationManager.AppSettings["cron"];27 ///28 ///构造函数29 /// 30 public SyncDataService()31 {32 InitializeComponent();33 //初始化34 logger = LogManager.GetLogger(this.GetType());35 //新建一个调度器工工厂36 ISchedulerFactory factory = new StdSchedulerFactory();37 //使用工厂生成一个调度器38 scheduler = factory.GetScheduler();39 40 }41 ///42 /// 服务开启43 /// 44 /// 45 protected override void OnStart(string[] args)46 {47 if (!scheduler.IsStarted)48 {49 //启动调度器50 scheduler.Start();51 //新建一个任务52 IJobDetail job = JobBuilder.Create().WithIdentity("AppLogJob", "AppLogJobGroup").Build();53 //新建一个触发器54 ITrigger trigger = TriggerBuilder.Create().StartNow().WithCronSchedule(StrCron).Build();55 //将任务与触发器关联起来放到调度器中56 scheduler.ScheduleJob(job, trigger);57 logger.Info("Quarzt 数据同步服务开启");58 }59 60 }61 /// 62 /// 服务停止63 /// 64 protected override void OnStop()65 {66 if (!scheduler.IsShutdown)67 {68 scheduler.Shutdown();69 }70 }71 ///72 /// 暂停73 /// 74 protected override void OnPause()75 {76 scheduler.PauseAll();77 base.OnPause();78 }79 ///80 /// 继续81 /// 82 protected override void OnContinue()83 {84 scheduler.ResumeAll();85 base.OnContinue();86 }87 }88 }
时间间隔采用的是cron表达式,关于cron表达式的定义,可以参考这篇文章:
定义Job,可以通过自定义类,并且实现IJob接口,可以很方便的定义一个任务,并且也非常容易扩展。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using Quartz; 7 using Quartz.Job; 8 namespace Statistics.WindowService.JobManager 9 { 10 ///11 /// 同步applog任务 12 /// 13 public class AppLogJob:IJob 14 { 15 //使用Common.Logging.dll日志接口实现日志记录 16 private static readonly Common.Logging.ILog logger = Common.Logging.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 17 ///18 /// 定时任务执行 19 /// 20 /// 21 public void Execute(IJobExecutionContext context) 22 { 23 try 24 { 25 logger.Info("AppLogJob 任务开始运行"); 26 27 for (int i = 0; i < 10; i++) 28 { 29 logger.InfoFormat("AppLogJob 正在运行{0}", i); 30 } 31 32 logger.Info("AppLogJob 任务运行结束"); 33 } 34 catch (Exception ex) 35 { 36 logger.Error("AppLogJob 运行异常", ex); 37 } 38 } 39 } 40 }
修改windows 服务的入口程序:
1 using System; 2 using System.Collections.Generic; 3 using System.Diagnostics; 4 using System.Linq; 5 using System.ServiceProcess; 6 using System.Text; 7 using System.Threading.Tasks; 8 9 namespace Statistics.WindowService10 {11 static class Program12 {13 ///14 /// 应用程序的主入口点。15 /// 16 static void Main(string[] args)17 {18 //如果传递了参数 s 就启动服务19 if (args.Length > 0 && args[0] == "s")20 {21 ServiceBase[] ServicesToRun;22 ServicesToRun = new ServiceBase[] { new SyncDataService() };23 ServiceBase.Run(ServicesToRun);24 }25 else26 {27 Console.WriteLine("这是Windows应用程序");28 Console.WriteLine("请选择,[1]安装服务 [2]卸载服务 [3]退出");29 var rs = int.Parse(Console.ReadLine());30 string strServiceName = "syncService[数据同步服务]";31 switch (rs)32 {33 case 1:34 //取当前可执行文件路径,加上"s"参数,证明是从windows服务启动该程序35 var path = Process.GetCurrentProcess().MainModule.FileName + " s";36 Process.Start("sc", "create " + strServiceName + " binpath= \"" + path + "\" displayName= " + strServiceName + " start= auto");37 Console.WriteLine("安装成功");38 Console.Read();39 break;40 case 2:41 Process.Start("sc", "delete " + strServiceName + "");42 Console.WriteLine("卸载成功");43 Console.Read();44 break;45 case 3: break;46 }47 48 }49 50 51 }52 }53 }
修改app.config
弄这个demo的目的是先让Quartz.net
找到bin目录下的exe文件,右键以管理员身份运行。查看生成的log日志
1 2015-05-22 10:43:23,115 INFO Quartz.Impl.StdSchedulerFactory - Default Quartz.NET properties loaded from embedded resource file 2 2015-05-22 10:43:23,147 INFO Quartz.Impl.StdSchedulerFactory - Using default implementation for object serializer 3 2015-05-22 10:43:23,168 INFO Quartz.Impl.StdSchedulerFactory - Using default implementation for ThreadExecutor 4 2015-05-22 10:43:23,181 INFO Quartz.Core.SchedulerSignalerImpl - Initialized Scheduler Signaller of type: Quartz.Core.SchedulerSignalerImpl 5 2015-05-22 10:43:23,181 INFO Quartz.Core.QuartzScheduler - Quartz Scheduler v.2.0.0.400 created. 6 2015-05-22 10:43:23,184 INFO Quartz.Simpl.RAMJobStore - RAMJobStore initialized. 7 2015-05-22 10:43:23,186 INFO Quartz.Core.QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.0.0.400) 'DefaultQuartzScheduler' with instanceId 'NON_CLUSTERED' 8 Scheduler class: 'Quartz.Core.QuartzScheduler' - running locally. 9 NOT STARTED.10 Currently in standby mode.11 Number of jobs executed: 012 Using thread pool 'Quartz.Simpl.SimpleThreadPool' - with 10 threads.13 Using job-store 'Quartz.Simpl.RAMJobStore' - which does not support persistence. and is not clustered.14 15 2015-05-22 10:43:23,186 INFO Quartz.Impl.StdSchedulerFactory - Quartz scheduler 'DefaultQuartzScheduler' initialized16 2015-05-22 10:43:23,187 INFO Quartz.Impl.StdSchedulerFactory - Quartz scheduler version: 2.0.0.40017 2015-05-22 10:43:23,191 INFO Quartz.Core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.18 2015-05-22 10:43:23,250 INFO Statistics.WindowService.SyncDataService - Quarzt 数据同步服务开启19 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务开始运行20 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行021 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行122 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行223 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行324 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行425 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行526 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行627 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行728 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行829 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行930 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务运行结束31 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务开始运行32 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行033 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行134 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行235 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行336 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行437 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行538 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行639 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行740 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行841 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行942 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务运行结束43 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务开始运行44 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行045 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行146 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行247 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行348 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行449 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行550 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行651 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行752 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行853 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行954 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务运行结束55 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务开始运行56 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行057 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行158 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行259 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行360 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行461 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行562 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行663 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行764 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行865 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行966 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务运行结束67 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务开始运行68 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行069 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行170 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行271 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行372 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行473 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行574 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行675 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行776 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行877 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行978 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务运行结束79 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务开始运行80 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行081 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行182 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行283 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行384 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行485 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行586 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行687 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行788 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行889 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行990 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务运行结束91 2015-05-22 10:49:17,048 INFO Quartz.Core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutting down.92 2015-05-22 10:49:17,048 INFO Quartz.Core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED paused.93 2015-05-22 10:49:17,052 INFO Quartz.Core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED Shutdown complete.
总结
内容很简单。只是将之前在博客园看到的一种方式在项目中实践了一下。
参考文章: