zoukankan      html  css  js  c++  java
  • 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:WindowsMicrosoft.NETFramework64v4.0.30319  InstallUtil C:IISQuatzServiceQuatz.Service.exe
    卸载服务 C:WindowsMicrosoft.NETFramework64v4.0.30319  InstallUtil /u C:IISQuatzServiceQuatz.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:IISQuatzServicequartz_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
    
  • 相关阅读:
    转:详解iPhone Tableview分批显示数据 点击加载更多
    能不写全局变量就不写全局变量。
    ios 打电话 一键拨号
    下一步目标:整理出1套相对成熟的ios 开发框架
    dispatch_sync 线程 GCD iOS
    iOS 播放声音 最简单的方法
    判断 网络是否通常,以及判断用户使用的网络类型,时2G\3G\还是wifi
    ios 特效 新思路 :加载gif 动画,然后在动画上增加点击事件即可。
    Oracle小技巧
    excel导出时”内存或磁盘空间不足“错误的解决方法
  • 原文地址:https://www.cnblogs.com/Irving/p/3427071.html
Copyright © 2011-2022 走看看