WorkerServices中使用Quartz.Net
前言
搞一个后台程序,定时去执行一些操作(定时任务)
本来想搞一个控制台程序,直接小黑框去运行,
但是都2021年了,想搞一个同样能在Linux下运行的程序...
(不出意外的话,这个程序的一生都上不了Linux...)
后来发现了Worker Service ...
新建项目 & 添加依赖项
新建Worker Service 项目
Visual Studio 2019 --> 文件-->新建项目-->Worker Service
添加依赖项
Install-Package Quartz.Extensions.Hosting -Version 3.3.1
Nuget.Quartz.Extensions.Hosting
上代码
Program.cs
public class Program
{
public static void Main(string[] args)
{
var configuration = GetConfiguration();
CreateHostBuilder(configuration, args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(IConfiguration configuration, string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureServices((hostContext, services) =>
{
// Add the required Quartz.NET services
services.AddQuartz(q =>
{
// Use a Scoped container to create jobs. I'll touch on this later
q.UseMicrosoftDependencyInjectionScopedJobFactory();
var jobModel = configuration.GetSection(nameof(JobModel)).Get<JobModel>() ?? throw new ArgumentNullException(nameof(configuration));
// Create a "key" for the job
var jobKey = new JobKey(jobModel.FilesSaveJobKey);
// Register the job with the DI container
q.AddJob<TestJob>(opts => opts.WithIdentity(jobKey));
// Create a trigger for the job
q.AddTrigger
(
opts =>
opts
// link to the HelloWorldJob
.ForJob(jobKey)
// give the trigger a unique name
.WithIdentity(jobModel.FilesSaveTriggerUniqueName)
//执行频率
.WithCronSchedule(jobModel.FilesSaveCronExpression)
);
});
// Add the Quartz.NET hosted service
services.AddQuartzHostedService
(
q => q.WaitForJobsToComplete = true
);
////问题记录,如何TestContext添加一个单例模式(这是另外一个问题,解决在Worker中注入DbContext)
//var mySqlModel = configuration.GetSection(nameof(MySQLModel)).Get<MySQLModel>() ?? throw new ArgumentNullException(nameof(configuration));
//services.AddSingleton<Func<TestContext>>(() =>
//{
// var optionsBuilder = new DbContextOptionsBuilder<DbContext>();
// optionsBuilder.UseMySQL(mySqlModel.ConnectionString);
// //如果有其他依赖的话,可以通过provider.GetService<XX>()来获取
// return new TestContext(optionsBuilder.Options);
//});
//services.AddSingleton<FileDownload>().AddSingleton<FileInfoUtility>();
//这个自带的方法直接注释即可.
//services.AddHostedService<Worker>();
});
private static IConfiguration GetConfiguration()
{
var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env}.json", true, false)
.AddEnvironmentVariables();
return builder.Build();
}
}
TestJob.cs
作业类
[DisallowConcurrentExecution]
public class TestJob : IJob
{
private readonly ILogger<TestJob> _logger;
private readonly ITestService _testService;
public TestJob
(
ILogger<TestJob> logger
, ITestService testService
)
{
_logger = logger;
_testService = testService;
}
public Task Execute(IJobExecutionContext context)
{
try
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
//主角-->男1号-->要定时执行的方法
var result = _testService.No1_Nan();
}
catch (Exception ex)
{
_testService.AddLogBusinessOperateAsync("运行-->异常", string.Concat(ex.Message, "-->", ex.InnerException?.Message));
_logger.LogError($"{DateTimeOffset.Now}-->{ex.Message}-->{ex.InnerException}");
}
return Task.CompletedTask;
}
}
总结
纸上得来终觉浅 Vs 纸上得来易躬行
有些问题你看了再多的资料,
但是不经历一次问题的起止(从发现问题,深入了解问题,解决问题)
真不搞不明白咋回事.
但是有些问题,
一篇好的资料,真的能帮你迅速解决问题.
对象 Vs 关联
我们可能隐约知道一个问题中,有哪些角色,
但是很少去梳理具体有哪些角色,并且关键梳理他们之间的关系,
比如这个问题中,
我本来梳理的涉及的角色[".NET Core","Quartz.Net","Worker Service"],
我要做的就是梳理清楚{Quartz.Net}和{Worker Service}之间的关系,如何关联,才能使这2者运行起来.
过了一段时间,经过我的了解,发现了一个新的角色-->{Quartz.Extensions.Hosting}(一个官方实现使用{Quartz.Net}运行后台任务)
并且官方出品,值得信赖,
所以现在涉及的角色-->[".NET Core","Quartz.Extensions.Hosting","Worker Service"]
关于{Quartz.Extensions.Hosting}和{Worker Service}之间的关系,
在一篇资料中也很好的演示了,我也少走了很多弯路,
直接复制过来,改下参数就可以用了.
并且其中一直有个误区,
{Worker Service}中自带了一个继承自{BackgroundService}的类-->{Worker},
我刚开始一直觉得必须要将{Quartz.Extensions.Hosting}和{Worker}关联起来,
一直觉得可能要在{Worker}中运行{Quartz.Extensions.Hosting}...
结果最后发现根本不需要{Worker}的参与...
真有人连最后一段话都看?
原博客写的特别好,
但是洋洋洒洒的大篇文本,
真的看不下去,
所以我最后这些文本大家可能也看不到...
我自己记录下.