Fork me on GitHub

Window服务与Quartz.NET

Quartz.NET: http://quartznet.sourceforge.net/ (现为2.2版本)
Sourceforge:
http://sourceforge.net/projects/quartznet/files/quartznet (项目打开貌似有点问题)
GitHub:
https://github.com/quartznet/quartznet
NuGet :
http://nuget.org/packages/Quartz
stackoverflow:
http://stackoverflow.com/questions/tagged/quartz.net

相对JAVA版的来说,文档太少了,我找了一个入门文档(QuartzNetQuickstart),基于XML配置的,个人认为配置更灵活,例如我写好一个服务,以后需要加任务,只需要写好实现类,修改下配置就行了。可以在如下地址下载:http://jayvilalta.com/blog/downloads/

在ASP.NET中使用,主要考虑到Application_End等一些列问题,现改用window服务。
http://asdfblog.com/technology/aspnet-scheduled-tasks-with-quartznet.html
http://blog.csdn.net/a497785609/article/details/5941283

Quartz.Net的组成

Common.Logging (一定注意版本2.1.2,或者使用相应的Nuget文件来获取)
C5(一个C#和其他CLI语言的泛型集合类, Net2.0及以上才可以使用,并支持 Mono
http://www.itu.dk/research/c5/)
quartz.config(有一个默认配置)

# Default Properties file for use by StdSchedulerFactory
# to create a Quartz Scheduler Instance, if a different
# properties file is not explicitly specified.
#
quartz.scheduler.instanceName = DefaultQuartzScheduler
quartz.threadPool.threadCount = 10
quartz.threadPool.threadPriority = Normal
quartz.jobStore.misfireThreshold = 60000

window服务

public partial class QuatzNTService : ServiceBase
  {
      private readonly ILog logger;
      private IScheduler scheduler;
      public QuatzNTService()
      {
          InitializeComponent();
          logger = LogManager.GetLogger(GetType());
          ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
          scheduler = schedulerFactory.GetScheduler();
      }
      protected override void OnStart(string[] args)
      {
          scheduler.Start();
          logger.Info("Quartz服务成功启动");
      }

      protected override void OnStop()
      {
          scheduler.Shutdown(true);
          logger.Info("Quartz服务成功终止");
      }

      protected override void OnPause()
      {
          scheduler.PauseAll();
      }

      protected override void OnContinue()
      {
          scheduler.ResumeAll();
      }
  }

任务

 /// <summary>
    /// This is just a simple job that says "Hello" to the world.
    /// </summary>
    /// <author>Bill Kratzer</author>
    /// <author>Marko Lahma (.NET)</author>
    public class HelloJob : IJob
    {
        private static readonly ILog logger = LogManager.GetLogger(typeof(HelloJob));

        /// <summary>
        /// Called by the <see cref="IScheduler" /> when a <see cref="ITrigger" />
        /// fires that is associated with the <see cref="IJob" />.
        /// </summary>
        /// <remarks>
        /// The implementation may wish to set a  result object on the 
        /// JobExecutionContext before this method exits.  The result itself
        /// is meaningless to Quartz, but may be informative to 
        /// <see cref="IJobListener" />s or 
        /// <see cref="ITriggerListener" />s that are watching the job's 
        /// execution.
        /// </remarks>
        /// <param name="context">The execution context.</param>
        public void Execute(IJobExecutionContext context)
        {
            logger.Info("HelloJob running...");
            Thread.Sleep(TimeSpan.FromSeconds(5));
            logger.Info("HelloJob run finished.");
        }

log4j

<?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.Log4net1211">
        <arg key="configType" value="INLINE" />
      </factoryAdapter>
    </logging>
  </common>

  <log4net>
    <!--控制台日志-->
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%d [%t] %-5p %l - %m%n" />
      </layout>
    </appender>
    <!--文本信息日志-->
    <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="ConsoleAppender" />
      <appender-ref ref="InfoFileAppender" />
      <appender-ref ref="ErrorFileAppender" />
      <!-- uncomment to enable event log appending -->
      <!--  <appender-ref ref="EventLogAppender" /> -->
    </root>
  </log4net>

  <!-- 
    We use quartz.config for this server, you can always use configuration section if you want to.
    Configuration section has precedence here.  
  -->
  <!--
 	<quartz>
		<add key="quartz.scheduler.instanceName" value="ExampleDefaultQuartzScheduler"/>

		<add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz"/>
		<add key="quartz.threadPool.threadCount" value="10"/>
		<add key="quartz.threadPool.threadPriority" value="2"/>

		<add key="quartz.jobStore.misfireThreshold" value="60000"/>
		<add key="quartz.jobStore.type" value="Quartz.Simpl.RAMJobStore, Quartz"/>
	</quartz>
  -->
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
</configuration>

配置

<?xml version="1.0" encoding="UTF-8"?>

<!-- This file contains job definitions in schema version 2.0 format -->

<job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">

  <processing-directives>
    <!-- 在计划作业和触发器是应遵循的命令和原则 -->
    <overwrite-existing-data>true</overwrite-existing-data>
  </processing-directives>

  <schedule>
    <job>
      <name>HelloJob</name>
      <group>HelloJobGroup</group>
      <description>Hello job for Quartz</description>
      <job-type>Quartz.Example.HelloJob, Quartz.Example</job-type>
      <durable>true</durable>
      <recover>false</recover>
    </job>
    <trigger>
      <cron>
        <name>HelloTrigger</name>
        <group>HelloTriggerGroup</group>
        <description>Simple trigger to simply fire sample job</description>
        <job-name>HelloJob</job-name>
        <job-group>HelloJobGroup</job-group>
        <!--每10秒中执行一次-->
        <cron-expression>0/10 * * * * ?</cron-expression>
      </cron>
    </trigger>

    <!--
    <trigger>
      <simple>
        <name>HelloTrigger</name>
        <group>HelloTriggerGroup</group>
        <description>Simple trigger to simply fire Hello job</description>
        <job-name>HelloJob</job-name>
        <job-group>HelloJobGroup</job-group>
        <misfire-instruction>SmartPolicy</misfire-instruction>
        <repeat-count>-1</repeat-count>
        <repeat-interval>10000</repeat-interval>
      </simple>
    </trigger>
   -->
  </schedule>
</job-scheduling-data>

安装服务 C:\Windows\Microsoft.NET\Framework64\v4.0.30319  InstallUtil C:\IIS\QuatzServiceQuatz.Service.exe
卸载服务 C:\Windows\Microsoft.NET\Framework64\v4.0.30319  InstallUtil /u C:\IIS\QuatzServiceQuatz.Service.exe

日志

2013-11-16 19:04:42,219 INFO  Quartz.Impl.StdSchedulerFactory  - Using default implementation for object serializer
2013-11-16 19:04:42,246 INFO  Quartz.Impl.StdSchedulerFactory  - Using default implementation for ThreadExecutor
2013-11-16 19:04:42,261 INFO  Quartz.Core.SchedulerSignalerImpl  - Initialized Scheduler Signaller of type: Quartz.Core.SchedulerSignalerImpl
2013-11-16 19:04:42,262 INFO  Quartz.Core.QuartzScheduler  - Quartz Scheduler v.2.2.400.0 created.
2013-11-16 19:04:42,268 INFO  Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin  - Registering Quartz Job Initialization Plug-in.
2013-11-16 19:04:42,270 INFO  Quartz.Simpl.RAMJobStore  - RAMJobStore initialized.
2013-11-16 19:04:42,284 INFO  Quartz.Simpl.RemotingSchedulerExporter  - Remoting is allowing remote calls
2013-11-16 19:04:42,285 INFO  Quartz.Simpl.RemotingSchedulerExporter  - Registering remoting channel of type 'System.Runtime.Remoting.Channels.Tcp.TcpChannel' to port (555) with name (httpQuartz)
2013-11-16 19:04:42,286 INFO  Quartz.Simpl.RemotingSchedulerExporter  - Remoting channel registered successfully
2013-11-16 19:04:42,287 INFO  Quartz.Simpl.RemotingSchedulerExporter  - Successfully marhalled remotable scheduler under name 'QuartzScheduler'
2013-11-16 19:04:42,290 INFO  Quartz.Core.QuartzScheduler  - Scheduler meta-data: Quartz Scheduler (v2.2.400.0) 'ServerScheduler' with instanceId 'NON_CLUSTERED'
  Scheduler class: 'Quartz.Core.QuartzScheduler' - access via remote incovation.
  NOT STARTED.
  Currently in standby mode.
  Number of jobs executed: 0
  Using thread pool 'Quartz.Simpl.SimpleThreadPool' - with 10 threads.
  Using job-store 'Quartz.Simpl.RAMJobStore' - which does not support persistence. and is not clustered.

2013-11-16 19:04:42,291 INFO  Quartz.Impl.StdSchedulerFactory  - Quartz scheduler 'ServerScheduler' initialized
2013-11-16 19:04:42,291 INFO  Quartz.Impl.StdSchedulerFactory  - Quartz scheduler version: 2.2.400.0
2013-11-16 19:04:42,301 INFO  Quartz.Xml.XMLSchedulingDataProcessor  - Parsing XML file: C:\IIS\QuatzService\quartz_jobs.xml with systemId: ~/quartz_jobs.xml
2013-11-16 19:04:42,492 INFO  Quartz.Xml.XMLSchedulingDataProcessor  - Adding 1 jobs, 1 triggers.
2013-11-16 19:04:42,496 INFO  Quartz.Xml.XMLSchedulingDataProcessor  - Adding job: HelloJobGroup.HelloJob
2013-11-16 19:04:42,534 INFO  Quartz.Core.QuartzScheduler  - Scheduler ServerScheduler_$_NON_CLUSTERED started.
2013-11-16 19:04:42,535 INFO  Quatz.Service.QuatzNTService  - Quartz服务成功启动
2013-11-16 19:04:50,019 INFO  Quartz.Example.HelloJob  - HelloJob running...
2013-11-16 19:04:55,021 INFO  Quartz.Example.HelloJob  - HelloJob run finished.
2013-11-16 19:05:00,001 INFO  Quartz.Example.HelloJob  - HelloJob running...
2013-11-16 19:05:05,002 INFO  Quartz.Example.HelloJob  - HelloJob run finished.
2013-11-16 19:05:10,000 INFO  Quartz.Example.HelloJob  - HelloJob running...
2013-11-16 19:05:15,000 INFO  Quartz.Example.HelloJob  - HelloJob run finished.
2013-11-16 19:05:19,999 INFO  Quartz.Example.HelloJob  - HelloJob running...
2013-11-16 19:05:25,000 INFO  Quartz.Example.HelloJob  - HelloJob run finished.
2013-11-16 19:05:30,000 INFO  Quartz.Example.HelloJob  - HelloJob running...
2013-11-16 19:05:35,000 INFO  Quartz.Example.HelloJob  - HelloJob run finished.
2013-11-16 19:05:40,000 INFO  Quartz.Example.HelloJob  - HelloJob running...
2013-11-16 19:05:45,000 INFO  Quartz.Example.HelloJob  - HelloJob run finished.
2013-11-16 19:05:49,999 INFO  Quartz.Example.HelloJob  - HelloJob running...
2013-11-16 19:05:54,999 INFO  Quartz.Example.HelloJob  - HelloJob run finished.
2013-11-16 19:06:00,000 INFO  Quartz.Example.HelloJob  - HelloJob running...
2013-11-16 19:06:05,000 INFO  Quartz.Example.HelloJob  - HelloJob run finished.
2013-11-16 19:06:10,004 INFO  Quartz.Example.HelloJob  - HelloJob running...
2013-11-16 19:06:15,005 INFO  Quartz.Example.HelloJob  - HelloJob run finished.
2013-11-16 19:06:20,000 INFO  Quartz.Example.HelloJob  - HelloJob running...
2013-11-16 19:06:25,000 INFO  Quartz.Example.HelloJob  - HelloJob run finish

 

 

 

posted @ 2013-11-16 19:18  花儿笑弯了腰  阅读(1658)  评论(0编辑  收藏  举报