• 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

  • 相关阅读:
    cf round #421 div2 D. Mister B and PR Shifts
    cf round #421 div2 C. Mister B and Boring Game(trick)
    UVa 12716 GCD XOR
    cf 821E Okabe and El Psy Kongroo(矩阵快速幂)
    hdu 6109 数据分割(并查集+set)
    poj 2887 Big String(块状链表)
    hdu 6119 小小粉丝度度熊(区间双指针)
    hdu 6118 度度熊的交易计划(可行费用流)
    hdu 6015 Gameia(树上博弈)
    hdu 6096 String(AC自动机巧妙建图)
  • 原文地址:https://www.cnblogs.com/wolf-sun/p/4523196.html
Copyright © 2020-2023  润新知