一.準備工作
- 創建.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 啓動服務。
- 安裝啓動成功後在服務裏面可以看到。
項目結構圖