quarz:用来灵活的调度程序的执行
topself:用来将应用提升为服务
一,建立控制台应用程序,引用右键添加:quarz.net,topself,topself.log4Net
二,main中添加代码,用topself承接程序的管理
using System
using Quartz;
using Topshelf;
using System.IO;
namespace Quarz
{
class Program
{
static void Main(string[] args)
{
try
{
log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "log4net.config"));
HostFactory.Run(x =>
{
x.UseLog4Net();//记录topself自己产生的日志
x.Service<ServiceRunner>(); //ServiceRunner是quarz的调度程序,以此来调用
x.SetDescription("自己的WindowsService调度中心");
x.SetDisplayName("CedarQuarz");
x.SetServiceName("CedarQuarz");
x.EnablePauseAndContinue();
});
}
catch (SchedulerException se)
{
Console.WriteLine(se);
}
}
}
}
//ServiceRunner.cs如下
using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Topshelf;
namespace Quarz
{
public sealed class ServiceRunner : ServiceControl, ServiceSuspend
{
private readonly IScheduler scheduler;
public ServiceRunner()
{
scheduler = StdSchedulerFactory.GetDefaultScheduler();//调用调度计划,在quarz_job.xml配置要执行的job
}
public bool Start(HostControl hostControl)
{
scheduler.Start();
return true;
}
public bool Stop(HostControl hostControl)
{
scheduler.Shutdown(false);
return true;
}
public bool Continue(HostControl hostControl)
{
scheduler.ResumeAll();
return true;
}
public bool Pause(HostControl hostControl)
{
scheduler.PauseAll();
return true;
}
}
}
//自己写的job实现ijob即可
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Quartz;
using System.Threading.Tasks;
using RTXSAPILib;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
namespace Quarz
{
class RtxSendMsg : IJob
{
private static RTXSAPILib.IRTXSAPIRootObj _RootObj;
public static RTXSAPILib.IRTXSAPIRootObj RootObj {
get {
if (_RootObj == null) {
_RootObj = new RTXSAPIRootObj();
}
return _RootObj;
}
}
public static string ServerIP= ConfigurationSettings.AppSettings["RtxServerIP"];
public static short ServerPort = short.Parse(ConfigurationSettings.AppSettings["RtxServerPort"]);
public static string ConnString = ConfigurationSettings.AppSettings["constring"];
public static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public void Execute(IJobExecutionContext context)
{
log.Info("开始");
//初始化服务器属性
try
{
RootObj.ServerIP = ServerIP;
RootObj.ServerPort = ServerPort; //设置服务器端口
DataTable dt = GetWaitNotifyInfo();
if (dt == null || dt.Rows.Count == 0) return;
foreach (DataRow dr in dt.Rows)
{
SendNotify(StringHelper.FormatObjToString(dr["receiverAccount"]),
StringHelper.FormatObjToString(dr["CustomerID"]),
StringHelper.FormatObjToString(dr["CustomerName"]),
StringHelper.FormatObjToString(dr["D_StartTime"]),
StringHelper.FormatObjToString(dr["title"]), StringHelper.FormatObjToInt(dr["holdtime"]), StringHelper.FormatObjToString(dr["content"]));
}
}
catch (Exception e) {
log.Error(e.StackTrace.ToString());
}
log.Info("结束");
//SendNotify("zhengxuesong", "hello", "", "【未接来电】客户65871于2015-10-16 14:10打来电话,请及时跟进");
}
public DataTable GetWaitNotifyInfo() {
SqlParameter[] storedParams =
{
new SqlParameter("@Code",""),
new SqlParameter("@UserID","")
};
IDataReader idr = Share.Data.SqlHelper.ExecuteReader(ConnString,
CommandType.StoredProcedure,
"GetWaitNotifyInfo",
storedParams);
DataTable dt = new DataTable();
dt.Load(idr);
return dt;
}
public static void SendNotify(string receiverAccount, string CustomerID, string CustomerName, string D_StartTime, string title, int holdtime, string content)
{
try
{
if (!RootObj.UserManager.IsUserExist(receiverAccount)) {
log.Warn(string.Format("{0}在腾讯通里不存在!", receiverAccount));
return ;
};
RootObj.SendNotify(receiverAccount, title, holdtime, content); //获取版本信息
log.Info(string.Format("{0},{1},{2},{3},{4},{5},{6}", receiverAccount, CustomerID, CustomerName, D_StartTime, title, holdtime, content));
}
catch (Exception xe)
{
log.Error(xe.StackTrace.ToString());
}
}
}
}
三,在app.config中指定job配置的xml文件,触发器的规格见文档
<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"/>
<!--******************************Plugin配置********************************************* -->
<add key="quartz.plugin.xml.type" value="Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz" />
<add key="quartz.plugin.xml.fileNames" value="~/quartz_jobs.xml"/>
</quartz>
四,quartz_jobs.xml如下
<?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>
<!--TestJob测试 任务配置-->
<job>
<name>RtxSendMsg</name>
<group>Rtx</group>
<description>向rtx发送提醒</description>
<job-type>Quarz.RtxSendMsg,Quarz</job-type>
<durable>true</durable>
<recover>false</recover>
</job>
<trigger>
<cron>
<name>向rtx发送提醒每10分钟</name>
<group>Rtx</group>
<job-name>RtxSendMsg</job-name>
<job-group>Rtx</job-group>
<start-time>2015-01-22T00:00:00+08:00</start-time>
<cron-expression>0 0/10 * * * ?</cron-expression>
</cron>
</trigger>
</schedule>
</job-scheduling-data>
五,注册服务在bin下执行
myapp.exe install myapp.exe start myapp.exe stop myapp.exe uninstall