Kada radite na web aplikacijama, često ćete trebati izvršavati određene zadatke u pozadini. U nekim će slučajevima to biti zadaci koje treba izvršiti u unaprijed definiranim intervalima.
Quartz.NET je .NET port otvorenog koda popularnog okvira za planiranje poslova Java. Dugo se koristi i pruža izvrsnu podršku za rad s Cron izrazima. Možete saznati više o Quartz.NET-u iz ranijeg posta ovdje.
Ovaj članak predstavlja raspravu o tome kako možemo raditi s Quartz.NET-om u ASP.NET Core za planiranje pozadinskih poslova.
Da biste radili s primjerima koda iz ovog članka, u sustavu biste trebali instalirati Visual Studio 2019. Ako još nemate kopiju, ovdje možete preuzeti Visual Studio 2019.
Stvorite projekt ASP.NET Core API
Prvo, kreirajmo ASP.NET Core projekt u Visual Studiju. Pod pretpostavkom da je Visual Studio 2019 instaliran u vašem sustavu, slijedite korake opisane u nastavku da biste u Visual Studiou stvorili novi ASP.NET Core projekt.
- Pokrenite Visual Studio IDE.
- Kliknite "Stvori novi projekt".
- U prozoru "Stvori novi projekt" s popisa predložaka odaberite "ASP.NET Core Web Application".
- Kliknite Dalje.
- U sljedećem prozoru "Konfiguriranje novog projekta" navedite naziv i mjesto za novi projekt.
- Kliknite Stvori.
- U prozoru "Stvori novu web-aplikaciju ASP.NET Core" odaberite .NET Core kao vrijeme izvođenja i ASP.NET Core 2.2 (ili noviju) s padajućeg popisa na vrhu. Ovdje ću koristiti ASP.NET Core 3.0.
- Odaberite "API" kao predložak projekta da biste stvorili novu aplikaciju ASP.NET Core API.
- Obavezno označite potvrdne okvire "Omogući podršku za Docker" i "Konfiguriraj za HTTPS" jer ovdje nećemo koristiti te značajke.
- Provjerite je li provjera autentičnosti postavljena na "Bez provjere autentičnosti" jer ni mi nećemo koristiti provjeru autentičnosti.
- Kliknite Stvori.
To će stvoriti novi ASP.NET Core API projekt u Visual Studiju. Odaberite mapu rješenja Controllers u prozoru Solution Explorer i kliknite "Dodaj -> Controller ..." da biste stvorili novi kontroler nazvan DefaultController.
Dalje, za rad s Quartzom trebali biste instalirati Quartz paket od NuGet-a. To možete učiniti putem upravitelja paketa NuGet unutar IDE-a Visual Studio 2019 ili izvršavanjem sljedeće naredbe na konzoli upravitelja paketa NuGet:
Instalirajte-paket kvarc
Quartz.NET poslovi, okidači i planeri
Tri glavna koncepta u Quartz.NET-u su poslovi, okidači i planeri. Posao sadrži kôd za izvršavanje zadatka ili posao koji treba izvršiti. Posao predstavlja klasa koja implementira IJob sučelje. Okidač se koristi za određivanje rasporeda i ostalih detalja posla. Možete iskoristiti okidač da odredite kako treba izvršiti posao. Planer je komponenta koja je odgovorna za anketiranje i izvršavanje poslova na temelju unaprijed definiranih rasporeda.
Stvorite rokovnik pomoću Quartz.NET
Treba napomenuti da u aplikaciji možete imati više planera. Međutim, ovdje ćemo koristiti jednostavnost jednog planera radi jednostavnosti. Sljedeći isječak koda ilustrira kako možete stvoriti instancu planera.
var planer = StdSchedulerFactory.GetDefaultScheduler (). GetAwaiter (). GetResult ();
Jednom kada je planer kreiran, možete koristiti sljedeći kôd u metodi ConfigureServices datoteke Startup.cs da biste dodali instancu planera kao jednokratnu uslugu.
services.AddSingleton (rokovnik);
Pokrenite i zaustavite rokovnik pomoću Quartz.NET
Za pokretanje i zaustavljanje planera iskoristit ćemo uslugu hostinga. Da biste to učinili, morate stvoriti klasu koja implementira sučelje IHostingService kako je prikazano u isječku koda koji je dat u nastavku.
javna klasa CustomQuartzHostedService: IHostedService{
privatno samo za čitanje IScheduler _scheduler;
javna CustomQuartzHostedService (planer ISchedulera)
{
_scheduler = rokovnik;
}
javni async zadatak StartAsync (CancellationToken cancellationToken)
{
await _scheduler? .Start (cancellationToken);
}
javni async zadatak StopAsync (CancellationToken cancellationToken)
{
await _scheduler? .Shutdown (cancellationToken);
}
}
Imajte na umu da biste trebali registrirati hostiranu uslugu u zbirci usluga u metodi ConfigureServices pomoću isječka koda navedenog u nastavku.
services.AddHostedService ();
Evo ažurirane metode ConfigureServices za vašu referencu:
javna praznina ConfigureServices (usluge IServiceCollection){
services.AddControllers ();
var planer =
StdSchedulerFactory.GetDefaultScheduler (). GetAwaiter (). GetResult ();
services.AddSingleton (rokovnik);
services.AddHostedService ();
}
Napravite posao pomoću Quartz.NET-a
Kao što sam ranije rekao, posao je klasa koja implementira IJob sučelje i sadrži metodu Execute (). Metoda Execute () prihvaća instancu tipa IJobExecutionContext.
Sljedeći isječak koda ilustrira klasu posla koja sadrži i asinkronu metodu Execute (). Ova metoda sadrži kod koji odgovara zadatku koji bi vaš posao trebao obaviti.
[DisallowConcurrentExecution]javni razred NotificationJob: IJob
{
privatno samo za čitanje ILogger _logger;
javni NotificationJob (zapisivač ILogger)
{
_logger = zapisničar;
}
javno izvršavanje zadatka (kontekst IJobExecutionContext)
{
_logger.LogInformation ("Pozdrav svijetu!");
return Task.CompletedTask;
}
}
Stvorite tvornicu poslova pomoću Quartz.NET-a
Tvornica poslova je klasa koja nasljeđuje sučelje IJobFactory i implementira metode NewJob () i ReturnJob (). Sljedeći isječak koda može se koristiti za stvaranje tvorničke klase koja može stvoriti i vratiti instancu posla.
javna klasa CustomQuartzJobFactory: IJobFactory{
privatno samo za čitanje IServiceProvider _serviceProvider;
javni CustomQuartzJobFactory (usluga ISroviceProviderProvider)
{
_serviceProvider = serviceProvider;
}
javni IJob NewJob (TriggerFiredBundle triggerFiredBundle,
Planer ISchedulera)
{
var jobDetail = triggerFiredBundle.JobDetail;
return (IJob) _serviceProvider.GetService (jobDetail.JobType);
}
public void ReturnJob (posao u IJob-u) {}
}
Imajte na umu da ova implementacija ne koristi spajanje poslova. Ako želite koristiti spremanje poslova, trebali biste promijeniti metodu NewJob (), a zatim implementirati metodu ReturnJob ().
Stvorite klasu JobMetadata za pohranu metapodataka posla
Upotrijebit ćemo prilagođenu klasu za spremanje metapodataka povezanih s poslom, tj. ID-a posla, imena itd. Sljedeća klasa predstavlja klasu metapodataka posla.
javni razred JobMetadata{
javni vodič za posao {get; postavljen; }
javni tip JobType {get; }
javni niz JobName {get; }
javni niz CronExpression {get; }
javni JobMetadata (Guid Id, Type jobType, string jobName,
string cronExpression)
{
JobId = Id;
JobType = tip posla;
JobName = ime posla;
CronExpression = cronExpression;
}
}
Stvorite hostiranu uslugu za pokretanje i zaustavljanje planera Quartz.NET
Dalje, trebat ćemo implementirati uslugu hostiranja. Hostirana usluga je klasa koja implementira sučelje IHostedService i pokreće kvarcni planer. Sljedeći popis kodova prikazuje prilagođenu hostiranu klasu usluge.
javna klasa CustomQuartzHostedService: IHostedService{
privatno samo za čitanje ISchedulerFactory planerFactory;
privatno samo za čitanje IJobFactory jobFactory;
privatno samo za čitanje JobMetadata jobMetadata;
javna CustomQuartzHostedService (ISchedulerFactory
planerFactory,
JobMetadata jobMetadata,
IJobFactory posaoFactory)
{
this.schedulerFactory = planeraFactory;
this.jobMetadata = jobMetadata;
this.jobFactory = jobFactory;
}
javni IScheduler Planer {get; postavljen; }
javni async zadatak StartAsync (CancellationToken cancellationToken)
{
Planer = čekati planerFactory.GetScheduler ();
Planer.JobFactory = tvornica posla;
var posao = CreateJob (jobMetadata);
var okidač = CreateTrigger (jobMetadata);
čekati Scheduler.ScheduleJob (posao, okidač, otkazivanjeToken);
čekati Scheduler.Start (cancellationToken);
}
javni async zadatak StopAsync (CancellationToken cancellationToken)
{
čekati Planera?? Isključivanje (cancellationToken);
}
privatni ITrigger CreateTrigger (JobMetadata jobMetadata)
{
vrati TriggerBuilder.Create ()
.WithIdentity (jobMetadata.JobId.ToString ())
.WithCronSchedule (jobMetadata.CronExpression)
.WithDescription ($ "{jobMetadata.JobName}")
.Izgraditi();
}
privatni IJobDetail CreateJob (JobMetadata jobMetadata)
{
vratiti JobBuilder
.Create (jobMetadata.JobType)
.WithIdentity (jobMetadata.JobId.ToString ())
.WithDescription ($ "{jobMetadata.JobName}")
.Izgraditi();
}
}
Sljedeći isječak koda prikazuje cjeloviti kôd metode ConfigureServices klase Startup.
javna praznina ConfigureServices (usluge IServiceCollection){
services.AddControllers ();
usluge.AddSingleton ();
usluge.AddSingleton ();
usluge.AddSingleton ();
services.AddSingleton (novi JobMetadata (Guid.NewGuid (), typeof (NotificationJob), "Notification Job", "0/10 * * * *?"));
services.AddHostedService ();
}
I to je sve što trebate učiniti! Kada izvršite aplikaciju, primijetit ćete da se metoda Execute () klase NotificationJob izvodi jednom u 10 sekundi.
Quartz.NET je dobar izbor za implementaciju planera u vaše aplikacije. Možete iskoristiti značajku postojanosti u Quartz.NET-u za pohranu svojih poslova u bazu podataka kao što su SQL Server, PostgreSQL ili SQLite.