Quartz.Net在windows服务中的使用
写在前面
这几天在弄一个项目,需要定时抓取一些数据,当时也想直接用timer算了。因为之前也弄过这样的项目,但是一想,已经用过了,再去使用同一种思路,未免太乏味了。就换了一种新玩法。这里将之前看到的一篇文章中提出的一个思路,在这个项目中实践了一下,发现乐在其中。
Quarzt.net
[转]C#创建服务及使用程序自动安装服务,.NET创建一个即是可执行程序又是Windows服务的exe
这篇文章,给了一种好玩的方式,并且自己也实践了一下,而且也确确实实在项目中用到了。
简单一个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.WindowService 17 { 18 /// <summary> 19 /// 数据同步windows服务 20 /// </summary> 21 public partial class SyncDataService : ServiceBase 22 { 23 private readonly ILog logger; 24 private IScheduler scheduler; 25 //时间间隔 26 private readonly string StrCron = ConfigurationManager.AppSettings["cron"] == null ? "* 10 * * * ?" : ConfigurationManager.AppSettings["cron"]; 27 /// <summary> 28 ///构造函数 29 /// </summary> 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 /// <summary> 42 /// 服务开启 43 /// </summary> 44 /// <param name="args"></param> 45 protected override void OnStart(string[] args) 46 { 47 if (!scheduler.IsStarted) 48 { 49 //启动调度器 50 scheduler.Start(); 51 //新建一个任务 52 IJobDetail job = JobBuilder.Create<AppLogJob>().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 /// <summary> 62 /// 服务停止 63 /// </summary> 64 protected override void OnStop() 65 { 66 if (!scheduler.IsShutdown) 67 { 68 scheduler.Shutdown(); 69 } 70 } 71 /// <summary> 72 /// 暂停 73 /// </summary> 74 protected override void OnPause() 75 { 76 scheduler.PauseAll(); 77 base.OnPause(); 78 } 79 /// <summary> 80 /// 继续 81 /// </summary> 82 protected override void OnContinue() 83 { 84 scheduler.ResumeAll(); 85 base.OnContinue(); 86 } 87 } 88 }
时间间隔采用的是cron表达式,关于cron表达式的定义,可以参考这篇文章:http://www.cnblogs.com/linjiqin/archive/2013/07/08/3178452.html
定义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 /// <summary>
11 /// 同步applog任务
12 /// </summary>
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 /// <summary>
18 /// 定时任务执行
19 /// </summary>
20 /// <param name="context"></param>
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.WindowService 10 { 11 static class Program 12 { 13 /// <summary> 14 /// 应用程序的主入口点。 15 /// </summary> 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 else 26 { 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
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089"/> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/> <sectionGroup name="common"> <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging"/> </sectionGroup> </configSections> <common> <logging> <factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4net"> <arg key="configType" value="INLINE"/> </factoryAdapter> </logging> </common> <log4net> <appender name="InfoFileAppender" type="log4net.Appender.RollingFileAppender"> <file value="log/" /> <appendToFile value="true" /> <param name="DatePattern" value="yyyyMMdd".txt"" /> <rollingStyle value="Date" /> <maxSizeRollBackups value="100" /> <maximumFileSize value="1024KB" /> <staticLogFileName value="false" /> <Encoding value="UTF-8" /> <filter type="log4net.Filter.LevelRangeFilter"> <param name="LevelMin" value="INFO" /> <param name="LevelMax" value="INFO" /> </filter> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date %-5level %logger - %message%newline" /> </layout> </appender> <appender name="ErrorFileAppender" type="log4net.Appender.RollingFileAppender"> <file value="log/error.txt" /> <appendToFile value="true" /> <rollingStyle value="Size" /> <maxSizeRollBackups value="100" /> <maximumFileSize value="10240KB" /> <staticLogFileName value="true" /> <Encoding value="UTF-8" /> <filter type="log4net.Filter.LevelRangeFilter"> <param name="LevelMin" value="WARN" /> <param name="LevelMax" value="FATAL" /> </filter> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date %-5level %logger - %message%newline" /> </layout> </appender> <root> <level value="INFO" /> <appender-ref ref="InfoFileAppender" /> <appender-ref ref="ErrorFileAppender" /> </root> </log4net> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> <appSettings> <!--每五分钟执行一次--> <add key="cron" value="* 5 * * * ?"/> </appSettings> </configuration>
弄这个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: 0 12 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' initialized 16 2015-05-22 10:43:23,187 INFO Quartz.Impl.StdSchedulerFactory - Quartz scheduler version: 2.0.0.400 17 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 正在运行0 21 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行1 22 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行2 23 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行3 24 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行4 25 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行5 26 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行6 27 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行7 28 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行8 29 2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行9 30 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 正在运行0 33 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行1 34 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行2 35 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行3 36 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行4 37 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行5 38 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行6 39 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行7 40 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行8 41 2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行9 42 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 正在运行0 45 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行1 46 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行2 47 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行3 48 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行4 49 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行5 50 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行6 51 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行7 52 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行8 53 2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行9 54 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 正在运行0 57 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行1 58 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行2 59 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行3 60 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行4 61 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行5 62 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行6 63 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行7 64 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行8 65 2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行9 66 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 正在运行0 69 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行1 70 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行2 71 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行3 72 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行4 73 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行5 74 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行6 75 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行7 76 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行8 77 2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行9 78 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 正在运行0 81 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行1 82 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行2 83 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行3 84 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行4 85 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行5 86 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行6 87 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行7 88 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行8 89 2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行9 90 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.
总结
内容很简单。只是将之前在博客园看到的一种方式在项目中实践了一下。
参考文章:
http://www.cnblogs.com/lzrabbit/archive/2012/04/15/2448326.html
-
博客地址:http://www.cnblogs.com/wolf-sun/
博客版权:如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步! 再次感谢您耐心的读完本篇文章。