前言
搞一個后台程序,定時去執行一些操作(定時任務)
本來想搞一個控制台程序,直接小黑框去運行,
但是都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}的參與...
真有人連最后一段話都看?
原博客寫的特別好,
但是洋洋灑灑的大篇文本,
真的看不下去,
所以我最后這些文本大家可能也看不到...
我自己記錄下.