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}的參與...


真有人連最后一段話都看?

原博客寫的特別好,
但是洋洋灑灑的大篇文本,
真的看不下去,
所以我最后這些文本大家可能也看不到...
我自己記錄下.




摘抄文檔


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM