一.安装nuget包

  • Install-Package Quartz
  • Install-Package Common.Logging.Log4Net1211
  • Install-Package log4net
  • Install-Package Topshelf

二.添加IQuartzServer接口类

/// <summary>
/// Service interface for core Quartz.NET server.
/// </summary>
public interface IQuartzServer
{
/// <summary>
/// Initializes the instance of <see cref="IQuartzServer"/>.
/// Initialization will only be called once in server's lifetime.
/// </summary>
void Initialize(); /// <summary>
/// Starts this instance.
/// </summary>
void Start(); /// <summary>
/// Stops this instance.
/// </summary>
void Stop(); /// <summary>
/// Pauses all activity in scheduler.
/// </summary>
void Pause(); /// <summary>
/// Resumes all activity in server.
/// </summary>
void Resume();
}
 

三.添加QuartzServer类实现接口

public class QuartzServer : ServiceControl, IQuartzServer
{
private readonly ILog logger;
private ISchedulerFactory schedulerFactory;
private IScheduler scheduler; /// <summary>
/// Initializes a new instance of the <see cref="QuartzServer"/> class.
/// </summary>
public QuartzServer()
{
logger = LogManager.GetLogger(GetType());
} /// <summary>
/// Initializes the instance of the <see cref="QuartzServer"/> class.
/// </summary>
public virtual void Initialize()
{
try
{
schedulerFactory = CreateSchedulerFactory();
scheduler = GetScheduler();
}
catch (Exception e)
{
logger.Error("Server initialization failed:" + e.Message, e);
throw;
}
} /// <summary>
/// Gets the scheduler with which this server should operate with.
/// </summary>
/// <returns></returns>
protected virtual IScheduler GetScheduler()
{
return schedulerFactory.GetScheduler();
} /// <summary>
/// Returns the current scheduler instance (usually created in <see cref="Initialize" />
/// using the <see cref="GetScheduler" /> method).
/// </summary>
protected virtual IScheduler Scheduler
{
get { return scheduler; }
} /// <summary>
/// Creates the scheduler factory that will be the factory
/// for all schedulers on this instance.
/// </summary>
/// <returns></returns>
protected virtual ISchedulerFactory CreateSchedulerFactory()
{
return new StdSchedulerFactory();
} /// <summary>
/// Starts this instance, delegates to scheduler.
/// </summary>
public virtual void Start()
{
try
{
scheduler.Start();
}
catch (Exception ex)
{
logger.Fatal(string.Format("Scheduler start failed: {0}", ex.Message), ex);
throw;
} logger.Info("Scheduler started successfully");
} /// <summary>
/// Stops this instance, delegates to scheduler.
/// </summary>
public virtual void Stop()
{
try
{
scheduler.Shutdown(true);
}
catch (Exception ex)
{
logger.Error(string.Format("Scheduler stop failed: {0}", ex.Message), ex);
throw;
} logger.Info("Scheduler shutdown complete");
} /// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public virtual void Dispose()
{
// no-op for now
} /// <summary>
/// Pauses all activity in scheduler.
/// </summary>
public virtual void Pause()
{
scheduler.PauseAll();
} /// <summary>
/// Resumes all activity in server.
/// </summary>
public void Resume()
{
scheduler.ResumeAll();
} /// <summary>
/// TopShelf's method delegated to <see cref="Start()"/>.
/// </summary>
public bool Start(HostControl hostControl)
{
Start();
return true;
} /// <summary>
/// TopShelf's method delegated to <see cref="Stop()"/>.
/// </summary>
public bool Stop(HostControl hostControl)
{
Stop();
return true;
} /// <summary>
/// TopShelf's method delegated to <see cref="Pause()"/>.
/// </summary>
public bool Pause(HostControl hostControl)
{
Pause();
return true;
} /// <summary>
/// TopShelf's method delegated to <see cref="Resume()"/>.
/// </summary>
public bool Continue(HostControl hostControl)
{
Resume();
return true;
}
}

四.添加服务工厂QuartzServerFactory

public class QuartzServerFactory
{
private static readonly ILog logger = LogManager.GetLogger(typeof(QuartzServerFactory)); /// <summary>
/// Creates a new instance of an Quartz.NET server core.
/// </summary>
/// <returns></returns>
public static QuartzServer CreateServer()
{
string typeName = "QuartzTest.QuartzServer"; Type t = Type.GetType(typeName, true); logger.Debug("Creating new instance of server type '" + typeName + "'");
QuartzServer retValue = (QuartzServer)Activator.CreateInstance(t);
logger.Debug("Instance successfully created");
return retValue;
}
}
 

五.添加Job类

/// <summary>
/// A sample job that just prints info on console for demostration purposes.
/// </summary>
public class SampleJob : IJob
{
private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
//private static readonly ILog logger = LogManager.GetLogger(typeof(SampleJob)); /// <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("SampleJob running...");
Thread.Sleep(TimeSpan.FromSeconds());
logger.Info("SampleJob run finished.");
}
}

六.添加quartz.config配置文件

# You can configure your scheduler in either <quartz> configuration section
# or in quartz properties file
# Configuration section has precedence quartz.scheduler.instanceName = ServerScheduler # configure thread pool info
quartz.threadPool.type = Quartz.Simpl.SimpleThreadPool, Quartz
quartz.threadPool.threadCount = 10
quartz.threadPool.threadPriority = Normal # job initialization plugin handles our xml reading, without it defaults are used
quartz.plugin.xml.type = Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz
quartz.plugin.xml.fileNames = ~/quartz_jobs.xml # export this server to remoting context
quartz.scheduler.exporter.type = Quartz.Simpl.RemotingSchedulerExporter, Quartz
quartz.scheduler.exporter.port = 555
quartz.scheduler.exporter.bindName = QuartzScheduler
quartz.scheduler.exporter.channelType = tcp
quartz.scheduler.exporter.channelName = httpQuartz

七.添加quartz_jobs.xml配置job

<?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>sampleJob</name>
<group>sampleGroup</group>
<description>Sample job for Quartz Server</description>
<job-type>QuartzTest.SampleJob, QuartzTest</job-type>
<durable>true</durable>
<recover>false</recover>
</job> <trigger>
<simple>
<name>sampleSimpleTrigger</name>
<group>sampleSimpleGroup</group>
<description>Simple trigger to simply fire sample job</description>
<job-name>sampleJob</job-name>
<job-group>sampleGroup</job-group>
<misfire-instruction>SmartPolicy</misfire-instruction>
<repeat-count>-1</repeat-count>
<repeat-interval>10000</repeat-interval>
</simple>
</trigger>
</schedule>
</job-scheduling-data>
 

八.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.Log4net1213">
<arg key="configType" value="INLINE" />
</factoryAdapter>
</logging>
</common> <log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<!--日志文件名开头-->
<file value="D:\Log\Quartz\log_"/>
<!--多线程时采用最小锁定-->
<lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
<!--日期的格式,每天换一个文件记录,如不设置则永远只记录一天的日志,需设置-->
<datePattern value="yyyyMMdd_HH".log""/>
<!--是否追加到文件,默认为true,通常无需设置-->
<appendToFile value="true"/>
<!--按照何种方式产生多个日志文件(日期[Date],文件大小[Size],混合[Composite])-->
<RollingStyle value="Composite"/>
<!--每天记录的日志文件个数,与maximumFileSize配合使用-->
<MaxSizeRollBackups value="100"/>
<!--每个日志文件的最大大小-->
<!--可用的单位:KB|MB|GB-->
<!--不要使用小数,否则会一直写入当前日志-->
<maximumFileSize value="2MB"/>
<!--是否只写到一个文件中-->
<staticLogFileName value="false" />
<!--日志格式-->
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%t]%-5p %c - %m%n"/>
</layout>
</appender>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d [%t] %-5p %l - %m%n" />
</layout>
</appender>
<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d [%t] %-5p %l - %m%n" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="ConsoleAppender" />
<appender-ref ref="RollingFileAppender" />
<!--控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF-->
<!-- uncomment to enable event log appending -->
<!-- <appender-ref ref="EventLogAppender" /> -->
</root>
</log4net> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
 

九.主程序代码

static void Main(string[] args)
{
log4net.Config.XmlConfigurator.Configure();
// change from service account's dir to more logical one
Directory.SetCurrentDirectory(System.AppDomain.CurrentDomain.BaseDirectory);
ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
logger.Info("日志开始");
HostFactory.Run(x =>
{
x.RunAsLocalSystem(); x.SetDescription("QuartzDemo服务描述");
x.SetDisplayName("QuartzDemo服务显示名称");
x.SetServiceName("QuartzDemo服务名称"); x.Service(factory =>
{
QuartzServer server = QuartzServerFactory.CreateServer();
server.Initialize();
return server;
});
});
}

十.运行

每10秒运行一次job
 
 
参考资料:
 

【10】Quartz.net 定时服务实例的更多相关文章

  1. quartz实现定时功能实例详解(servlet定时器配置方法)

    Quartz是一个完全由java编写的开源作业调度框架,下面提供一个小例子供大家参考,还有在servlet配置的方法 Quartz是一个完全由java编写的开源作业调度框架,具体的介绍可到http:/ ...

  2. Quartz.Net 定时服务

    http://www.cnblogs.com/jys509/p/4628926.html https://www.cnblogs.com/AmyLo/p/8125505.html https://bl ...

  3. LBPL--基于Asp.net、 quartz.net 快速开发定时服务的插件化项目

    LBPL 这一个基于Asp.net. quartz.net 快速开发定时服务的插件化项目 由于在实际项目开发中需要做定时服务的操作,大体上可以理解为:需要动态化监控定时任务的调度系统. 为了实现快速开 ...

  4. Spring定时服务QuartZ

    在JavaEE系统中,我们会经常用到定时任务,比如每天凌晨生成前天报表,每一小时生成汇总数据等等. 我们可以使用java.util.Timer结合java.util.TimerTask来完成这项工作, ...

  5. Quartz.NET+TopSelf 实现定时服务

    转载http://www.cnblogs.com/jys509/p/4628926.html Quartz.NET 入门 2015-07-09 00:59 by jiangys, 67858 阅读,  ...

  6. Topshelf结合Quartz.NET实现服务端定时调度任务

    这周接受到一个新的需求:一天内分时间段定时轮询一个第三方WebAPI,并保存第三方WebAPI结果. 需求分析:分时段.定时开启.定时结束.轮询.主要工作集中在前三个上,轮询其实就是个Http请求,比 ...

  7. 第九章 Net 5.0 快速开发框架 YC.Boilerplate --定时服务 Quartz.net

    在线文档:http://doc.yc-l.com/#/README 在线演示地址:http://yc.yc-l.com/#/login 源码github:https://github.com/linb ...

  8. Quartz.NET Windows 服务示例

    想必大家在项目中处理简单的后台持续任务或者定时触发任务的时候均使用 Thread 或者 Task 来完成,但是项目中的这种需求一旦多了的话就得将任务调度引入进来了,那今天就简单的介绍一下 Quartz ...

  9. Quartz.net 定时任务在IIS中未按时执行

    IIS 垃圾回收机制下解决Quartz.net 的不执行问题 IIS中涉及了垃圾回收机制,quartz.net 在ASP.NET 项目中可以实现线程监控定时执行任务,但是在IIS7.5机一下版本中涉及 ...

随机推荐

  1. G - Ice_cream's world I (并查集)

    点击打开链接 ice_cream's world is a rich country, it has many fertile lands. Today, the queen of ice_cream ...

  2. Spring中 使用注解+c3p0+事物 《模拟银行转账》

    使用注解的方式  模拟转账 要么都成功 要么都失败 !保持一致性! 准备工作: jar包:  需要的类:       UserDao: package com.hxzy.spring.c3p0.Dao ...

  3. java的string和==和equals和hashcode简单理解

    String s1= "abc"; s1是引用变量,在栈里面,如果java的String常量池中没有abc,则开拓一块区域存abc,s1指向常量池中的abc: String s2= ...

  4. 爬虫5:beautifulsoup

      灵活方便的网页解析库,处理高效,支持多种解析器,利用它不用编写正则表达式即可方便的实现网页信息的提取     一. BeautifulSoup的几种解析库   解析器 使用方法 优势 劣势 Pyt ...

  5. Class文件分析

    java源码和class文件 源码: package classloader; public class TestCase { private int value; public int test() ...

  6. 4. STL编程四

    1. 类模板的默认参数规则: #include <iostream> using namespace std; /* //类模板,不调用不编译(函数):变量还是规范 template< ...

  7. TCP 和 UDP 协议

    TCP 和 UDP 协议 一.socket层 Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐 ...

  8. JSP入门之自定义标签

    第二部分简单讲解:主要讲解el表达式,核心标签库.本章主要讲解:自定义标签库:404页面,505页面,错误页面配置方法 全部代码下载:链接 1.JSP自定义标签: 自定义标签是用户定义的JSP语言元素 ...

  9. openproject安装与使用

    思路: 1.生成config配置文件 2.导出配置文件,修改配置文件,删除容器,重新部署容器 3.登录后配置, 4.配置git,可以从openproject里查看gitlab上的代码库 第一次安装: ...

  10. shell-008:检测502

    检测502的方法有多种 1.curl他的状态码(不建议,会对网站造成不必要的访问和多余的日志输出) 2.可以直接检测访问日志 下面用while做成一个死循环监控日志502的状态 #!/bin/bash ...