Quartz.Net在windows服务中的使用

写在前面

这几天在弄一个项目,需要定时抓取一些数据,当时也想直接用timer算了。因为之前也弄过这样的项目,但是一想,已经用过了,再去使用同一种思路,未免太乏味了。就换了一种新玩法。这里将之前看到的一篇文章中提出的一个思路,在这个项目中实践了一下,发现乐在其中。

Quarzt.net

[转]C#创建服务及使用程序自动安装服务,.NET创建一个即是可执行程序又是Windows服务的exe

这篇文章,给了一种好玩的方式,并且自己也实践了一下,而且也确确实实在项目中用到了。

简单一个demo,先熟悉如何使用Quartz.NET

Quartz.Net在windows服务中的使用

关于如何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文件,右键以管理员身份运行。

Quartz.Net在windows服务中的使用

查看生成的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

你可能感兴趣的:(windows)