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&quot;.txt&quot;" />
      <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

posted @ 2015-05-22 20:01  wolfy  阅读(6620)  评论(0编辑  收藏  举报