一.准备工作
- 创建.net core 控制台应用程序
- 添加NuGet程序包
二.配置Quartz
- 创建appsettings.json文件,右键文件属性,并更改属性为始终复制 内容
"quartz": {
"scheduler": {
"instanceName": "CoreSolution.Job"
},
"threadPool": {
"type": "Quartz.Simpl.SimpleThreadPool, Quartz",
"threadPriority": "Normal",
"threadCount": 10
},
"plugin": {
"jobInitializer": {
"type": "Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz.Plugins",
"fileNames": "quartz_jobs.xml"
}
}
}
三.创建QuartzOption 类
public class QuartzOption
{
public QuartzOption(IConfiguration config)
{
if (config == null)
{
throw new ArgumentNullException(nameof(config));
}
var section = config.GetSection("quartz");
section.Bind(this);
}
public Scheduler Scheduler { get; set; }
public ThreadPool ThreadPool { get; set; }
public Plugin Plugin { get; set; }
public NameValueCollection ToProperties()
{
var properties = new NameValueCollection
{
["quartz.scheduler.instanceName"] = Scheduler?.InstanceName,
["quartz.threadPool.type"] = ThreadPool?.Type,
["quartz.threadPool.threadPriority"] = ThreadPool?.ThreadPriority,
["quartz.threadPool.threadCount"] = ThreadPool?.ThreadCount.ToString(),
["quartz.plugin.jobInitializer.type"] = Plugin?.JobInitializer?.Type,
["quartz.plugin.jobInitializer.fileNames"] = Plugin?.JobInitializer?.FileNames
};
return properties;
}
}
public class Scheduler
{
public string InstanceName { get; set; }
}
public class ThreadPool
{
public string Type { get; set; }
public string ThreadPriority { get; set; }
public int ThreadCount { get; set; }
}
public class Plugin
{
public JobInitializer JobInitializer { get; set; }
}
public class JobInitializer
{
public string Type { get; set; }
public string FileNames { get; set; }
}
四.添加一个job
- 需要继承IJob接口
public class TestJob : IJob
{
public Task Execute(IJobExecutionContext context)
{
//你的业务代码....
WriteLogHelper.WriteLogMany("开始执行testJob");
return Task.FromResult(true);
}
}
五.实现IJobFactory
public class JobFactory : IJobFactory
{
protected readonly IServiceProvider Container;
public JobFactory(IServiceProvider container)
{
Container = container;
}
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
return Container.GetService(bundle.JobDetail.JobType) as IJob;
}
public void ReturnJob(IJob job)
{
(job as IDisposable)?.Dispose();
}
}
六.创建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>TestJob</name>
<group>Test</group>
<description>TestJob测试</description>
<job-type>CoreSolution.Job.jobs.TestJob,CoreSolution.Job</job-type>
<durable>true</durable>
<recover>false</recover>
</job>
<trigger>
<cron>
<name>TestJobTrigger</name>
<group>Test</group>
<job-name>TestJob</job-name>
<job-group>Test</job-group>
<cron-expression>0 0 1 * * ?</cron-expression>
<!--每天凌晨1点执行一次-->
</cron>
</trigger>
<!--TestJob2测试 任务配置-->
<job>
<name>TestJob2</name>
<group>Test</group>
<description>TestJob2测试</description>
<job-type>CoreSolution.Job.jobs.TestJob2,CoreSolution.Job</job-type>
<durable>true</durable>
<recover>false</recover>
</job>
<trigger>
<cron>
<name>TestJob2Trigger</name>
<group>Test</group>
<job-name>TestJob2</job-name>
<job-group>Test</job-group>
<cron-expression>0/30 * * * * ?</cron-expression>
<!--30s执行一次-->
</cron>
</trigger>
</schedule>
</job-scheduling-data>
七.添加QuartzServer
public class QuartzServer : ServiceControl, ServiceSuspend
{
//调度器
private IScheduler scheduler;
public QuartzServer()
{
scheduler = StdSchedulerFactory.GetDefaultScheduler().GetAwaiter().GetResult();
}
public bool Start(HostControl hostControl)
{
scheduler.Start();
Console.WriteLine("Quartz任务调度启动");
return true;
}
public bool Continue(HostControl hostControl)
{
scheduler.ResumeAll();
return true;
}
public bool Pause(HostControl hostControl)
{
scheduler.PauseAll();
return true;
}
public bool Stop(HostControl hostControl)
{
scheduler.Shutdown();
Console.WriteLine("Quartz任务调度关闭");
return true;
}
}
八.配置TopShelf
public class Program
{
static void Main(string[] args)
{
var rc = HostFactory.Run(x =>
{
x.Service<QuartzServer>(s =>
{
s.ConstructUsing(name => new QuartzServer());
s.WhenStarted((tc, hc) => tc.Start(hc));
s.WhenStopped((tc, hc) => tc.Stop(hc));
s.WhenContinued((tc, hc) => tc.Continue(hc));
s.WhenPaused((tc, hc) => tc.Pause(hc));
});
x.RunAsLocalSystem();//使用本地服务账户运行
x.SetDescription("QuartzAndTopshelf服务描述");//服务描述
x.SetDisplayName("QuartzAndTopshelf");//服务显示名称
x.SetServiceName("QuartzAndTopshelf");//服务名称
});
var exitCode = (int)Convert.ChangeType(rc, rc.GetTypeCode());
Environment.ExitCode = exitCode;
Console.ReadKey();
}
}
在项目文件中加上项目的运行环境相关配置
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
</PropertyGroup>
运行
- 项目编译完成后进入bin\Debug\netcoreapp2.1\win10-x64目录,在此处以管理员运行cmd,然后执行依次CoreSolution.Job.exe install 安装服务 ,CoreSolution.Job.exe start 启动服务。
- 安装启动成功后在服务里面可以看到。
项目结构图