日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

ASP.NET Core托管运行Quartz.NET作业调度详解

發(fā)布時間:2023/12/4 asp.net 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ASP.NET Core托管运行Quartz.NET作业调度详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Quartz.NET這么NB的作業(yè)調(diào)度系統(tǒng),不會還行?

?

今天介紹一下Quartz.NET的托管運行,官網(wǎng)傳送門。

一、前言

Quartz.NET,按官網(wǎng)上的說法,是一款功能齊全的任務(wù)調(diào)度系統(tǒng),從小型應(yīng)用到大型企業(yè)級系統(tǒng)都能適用。在眾多項目中,Quartz.NET以可靠、集群的方式,被用作在定時器上運行后臺任務(wù)的一種方式。

Quartz.NET主要完成兩個方面的內(nèi)容:

  • 基于時間計劃的后臺作業(yè);

  • 基于因時間計劃的觸發(fā)的任務(wù)運行。

  • ?

    ASP.NET Core本身對于通過托管服務(wù)運行后臺任務(wù)就支持的很好。當(dāng)ASP.NET啟動托管服務(wù)時,應(yīng)用程序啟動,并在生命周期內(nèi)在后臺運行。通過創(chuàng)建Quartz.NET托管服務(wù),可以使用標(biāo)準(zhǔn)的.Net Core托管服務(wù),在后臺運行任務(wù)。

    Quartz.NET可以創(chuàng)建定時的任務(wù),例如每十分鐘運行一個任務(wù)。除此之外,Quartz.NET還可以通過Cron觸發(fā)器,定義任務(wù)在特定的日子或特定的時間運行,例如每天凌晨兩點執(zhí)行一個任務(wù)。它還允許以集群的方式運行應(yīng)用程序的多個實例,以便在任何時間確保只有一個實例運行給定的任務(wù)。

    ?

    下面,就針對這些特性和功能,進行詳細的說明。

    二、安裝Quartz.NET

    Quartz.NET提供了NuGet包,所以安裝很簡單:

    %?dotnet?add?package?quartz

    這是個司機就知道,不詳說了。

    看一下安裝后的.csproj文件內(nèi)容:

    <Project?Sdk="Microsoft.NET.Sdk.Web"><PropertyGroup><TargetFramework>netcoreapp3.1</TargetFramework></PropertyGroup><ItemGroup><PackageReference?Include="quartz"?Version="3.2.2"?/></ItemGroup> </Project>

    三、通過IJob創(chuàng)建任務(wù)類

    我們用個例子來說明 - 創(chuàng)建一個Demo的實現(xiàn)。它將寫入ILogger<>。我們會使用Quartz.NET的接口IJob來實現(xiàn),并使用依賴注入將日志注入到構(gòu)造函數(shù)中。

    [DisallowConcurrentExecution] public?class?DemoJob?:?IJob {private?readonly?ILogger<DemoJob>?_logger;public?DemoJob(ILogger<DemoJob>?logger){_logger?=?logger;}public?Task?Execute(IJobExecutionContext?context){_logger.LogInformation("Demo?!");return?Task.CompletedTask;} }

    在類的前面,我用了一個DisallowConcurrentExecution屬性。這個屬性可以防止Quartz.NET同時運行相同的作業(yè)。

    四、通過IJobFactory創(chuàng)建任務(wù)工廠

    通常情況下,Quartz.NET會使用Activator.CreateInstance來創(chuàng)建作業(yè)的實例。

    在我們這個例子里,我們換一種方式。使用IJobFactory實現(xiàn),并與ASP.NET Core的依賴注入容器掛鉤。

    public?class?SingletonJobFactory?:?IJobFactory {private?readonly?IServiceProvider?_serviceProvider;public?SingletonJobFactory(IServiceProvider?serviceProvider){_serviceProvider?=?serviceProvider;}public?IJob?NewJob(TriggerFiredBundle?bundle,?IScheduler?scheduler){return?_serviceProvider.GetRequiredService(bundle.JobDetail.JobType)?as?IJob;}public?void?ReturnJob(IJob?job){} }

    這個IJobFactory的實現(xiàn),在構(gòu)造函數(shù)中引入IServiceProvider,并實現(xiàn)接口。

    接口中,最重要的是NewJob()方法。這個方法需要返回Quartz.NET調(diào)度器請求的IJob。在我們的例子中,我們直接委托給IServiceProvider,并讓DI容器找到所需的實例。

    ReturnJob()方法是調(diào)度程序返回和銷毀IJobFactory創(chuàng)建的作業(yè)的地方。不過,因為我們使用了IServiceProvider,而它沒有提供這樣的處理。所以,從安全的角度,應(yīng)該使用單例作業(yè)。

    五、配置作業(yè)

    在第三節(jié)中,我們創(chuàng)建了一個IJob的實現(xiàn)。這個實現(xiàn)直接使用就可以。

    但是,我們這兒要加點內(nèi)容。我們把Quartz的托管服務(wù)做成一個通用實現(xiàn),來調(diào)度任意的作業(yè)。因此,我們創(chuàng)建一個簡單的DTO,并使用它來定義一個給定作業(yè)類型的時間器調(diào)度:

    public?class?JobSchedule {public?JobSchedule(Type?jobType,?string?cronExpression){JobType?=?jobType;CronExpression?=?cronExpression;}public?Type?JobType?{?get;?}public?string?CronExpression?{?get;?} }

    在這個類中,JobType是一個作業(yè)的類型,例如本例子中的DemoJob。CronExpression是一個Cron的表達式。

    Cron表達式允許復(fù)雜的計時器調(diào)度,所以可以設(shè)置規(guī)則,比如每個月的5號和20號,在早上8點到10點之間每半小時觸發(fā)一次。

    關(guān)于Quartz.NET的Cron表達式,可以在這兒查到。

    注意:不同操作系統(tǒng)使用的Cron表達式有一定的區(qū)別,寫表達式的時候一定要注意這一點。

    ?

    然后,我們把作業(yè)添加到Startup.ConfigureServices()中:

    public?void?ConfigureServices(IServiceCollection?services) {services.AddControllers();services.AddSingleton<IJobFactory,?SingletonJobFactory>();services.AddSingleton<ISchedulerFactory,?StdSchedulerFactory>();services.AddSingleton<DemoJob>();services.AddSingleton(new?JobSchedule(jobType:?typeof(DemoJob),cronExpression:?"0/5?*?*?*?*??"));?//?每5秒運行一次 }

    這段代碼向DI添加了四個單例對象:

  • SingletonJobFactory,第四節(jié)的類,用于創(chuàng)建作業(yè)實例;

  • ISchedulerFactory的一個實現(xiàn),是內(nèi)置的StdSchedulerFactory,用于處理調(diào)度和管理作業(yè);

  • DemoJob作業(yè)本身;

  • DemoJob的一個JobSchedule實例,該實例具有每5秒運行一次的Cron表達式。

  • ?

    現(xiàn)在,主要代碼已經(jīng)完成,就差Quartz托管服務(wù)了。

    六、創(chuàng)建Quartz托管服務(wù)

    QuartzHostedService是自己創(chuàng)建的Quartz托管服務(wù),繼承于IHostedService,用于設(shè)置Quartz調(diào)度器,并在后臺啟動它。

    先看一下完整的代碼:

    public?class?QuartzHostedService?:?IHostedService {private?readonly?ISchedulerFactory?_schedulerFactory;private?readonly?IJobFactory?_jobFactory;private?readonly?IEnumerable<JobSchedule>?_jobSchedules;public?QuartzHostedService(ISchedulerFactory?schedulerFactory,?IJobFactory?jobFactory,?IEnumerable<JobSchedule>?jobSchedules){_schedulerFactory?=?schedulerFactory;_jobSchedules?=?jobSchedules;_jobFactory?=?jobFactory;}public?IScheduler?Scheduler?{?get;?set;?}public?async?Task?StartAsync(CancellationToken?cancellationToken){Scheduler?=?await?_schedulerFactory.GetScheduler(cancellationToken);Scheduler.JobFactory?=?_jobFactory;?foreach?(var?jobSchedule?in?_jobSchedules){var?job?=?CreateJob(jobSchedule);var?trigger?=?CreateTrigger(jobSchedule);await?Scheduler.ScheduleJob(job,?trigger,?cancellationToken);}await?Scheduler.Start(cancellationToken);}public?async?Task?StopAsync(CancellationToken?cancellationToken){await?Scheduler?.Shutdown(cancellationToken);}private?ITrigger?CreateTrigger(JobSchedule?schedule){return?TriggerBuilder.Create().WithIdentity($"{schedule.JobType.FullName}.trigger").WithCronSchedule(schedule.CronExpression).WithDescription(schedule.CronExpression).Build();}private?IJobDetail?CreateJob(JobSchedule?schedule){var?jobType?=?schedule.JobType;return?JobBuilder.Create(jobType).WithIdentity(jobType.FullName).WithDescription(jobType.Name).Build();} }

    解釋一下這段代碼:

    這段代碼中,QuartzHostedService有三個依賴項:Startup.ConfigureServices()中注入的ISchedulerFactory和IJobFactory,以及一個IEnumerable。在第五節(jié)的代碼中,我們只向DI添加了一個JobSchedule,就是DemoJob。我們也可以添加多個JobSchedule,他們都會在這個IEnumerable中被注入到托管服務(wù)中。

    StartAsync在應(yīng)用程序啟動時被調(diào)用,它是我們配置Quartz的地方。我們首先創(chuàng)建IScheduler的一個實例,為它分配一個屬性供以后使用,并將調(diào)度程序的JobFactory設(shè)置為注入的實例:

    public?async?Task?StartAsync(CancellationToken?cancellationToken) {Scheduler?=?await?_schedulerFactory.GetScheduler(cancellationToken);Scheduler.JobFactory?=?_jobFactory;?//...? }

    然后,循環(huán)注入的作業(yè)調(diào)度,并在類的最后使用CreateJob和CreateTrigger方法為每個作業(yè)創(chuàng)建一個IJobDetail和ITrigger。實際應(yīng)用中如果有別的需要,也可以通過擴展JobSchedule?DTO來定制它。

    最后,在調(diào)度了所有作業(yè)之后,調(diào)用Scheduler.Start()來實際在后臺啟動Quartz.NET調(diào)度器。當(dāng)應(yīng)用程序關(guān)閉時,框架將調(diào)用StopAsync(),此時可以調(diào)用Scheduler.Shutdown()來安全地關(guān)閉調(diào)度程序進程。

    ?

    全部完成后,我們啟動QuartzHostedService:

    public?void?ConfigureServices(IServiceCollection?services) {//?...services.AddHostedService<QuartzHostedService>(); }

    ?

    運行程序,可以看到結(jié)果:

    demo.DemoJob:?Information:?Demo?! info:?demo.DemoJob[0]Demo?! demo.DemoJob:?Information:?Demo?! info:?demo.DemoJob[0]Demo?! demo.DemoJob:?Information:?Demo?! info:?demo.DemoJob[0]Demo?! demo.DemoJob:?Information:?Demo?! info:?demo.DemoJob[0]Demo?!

    本文的代碼,在https://github.com/humornif/Demo-Code/tree/master/0029/demo

    喜歡就來個三連,讓更多人因你而受益

    創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

    總結(jié)

    以上是生活随笔為你收集整理的ASP.NET Core托管运行Quartz.NET作业调度详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。