
Teknik Muhabbetler #7 (Cron Job,IHostedService, EasyCronJob)
“İnsanlar ne yaptığınızla değil neden yaptığınızla ilgilenir.”
Teknik muhabbetler serisinin bu yazısına son zamanlarda okuduğum ve mesleğe karşı bakış açımı değiştiren “Neden İle Başla” kitabından bir cümle ile başlamak istedim. Bu cümlede geçen insanlar kelimesi oldukça soyut. Kim bu insanlar? Eşimiz, ailemiz, müşterilerimiz, takım arkadaşlarımız bazen ise kendimiz. Her ne olursa olsun bu insanlara ilham vermek veya bakış açılarını zenginleştirmek istiyorsanız onlara “Neden” sorusunun önemini anlatın. Yeter mi? Hayır. Sizler de her zaman “Neden” sorusunun önemini bilen insanlarla ömrümünüzü geçirin. Bu yazıda teknik bir konu üzerinde neden sorusunu soracağız. Bu soruyu sormakla kalmayıp bir çözüm önerisi sunmaya çalışacağız. Bu kadar felsefe yeter. Hadi başlayalım. 🎉
Sektörde bir BackEnd Developer olarak çalışıyorsanız mutlaka CronJob
, ScheduledJob
veya RecurringJob
kavramlarını duymuşsunuzdur. Kısaca özetlemek gerekirse “Bir görevi uygulamaya gelen isteklerden bağımsız bir şekilde tamamlayan zamanlanmış iş parçacıklarıdır.” diyebiliriz.
Örneğin;
- Doğum tarihi bugün olan kullanıcıların hepsine email gönder.
- Bir gün önce gerçekleşen başarılı siparişlerin toplam tutarını hesapla.
- Gün içinde randevusu olan kullanıcılara hatırlatma bildirimi gönder.
vb.
Bu tarz işlerde eğer .Net ekosistemine hakim bir geliştiriciyseniz aklınıza hemen Hangfire veya Quartz kütüphaneleri gelir. Ben günlük hayatta genellikle Hangfire kullanıyorum. Tabii birbirlerine göre avantajları/dezavantajları vardır ancak bu yazının konusu bu iki kütüphaneyi karşılaştırmak değil.
.Net Core 2.1'in piyasaya sürülmesiyle arka plan işlerimizi IHostedService
üzerinde barındırabiliriz. Hadi öğrenelim. 🧐
Cron işlerimizi tanımlarken kullandığımız Cron Expression
olarak isimlendirilen ifadeleri öğrenmekte fayda var. Konuyu çok uzatmadan ilgili wikepedia linkini buraya bırakıyorum. Oluşturduğumuz cron ifadelerinin ne anlama geldiğini öğrenmek için şu siteyi ziyaret edebilirsiniz.
Oluşturduğumuz cron ifadelerini parse etmek ve kullanmak için Hangfire tarafından geliştirilmiş Cronos
kütüphanesini kullanacağız.
Cron işlerinin tanımlanması ve çalıştırılması için bir base sınıfa ihtiyacımız var. Daha sonra bu base sınıfı kullanıp kendi cron işlerimizi tanımlayacağımız için Abstract
class yapmakta fayda var. Sanırım Interface
ile Abstract
arasındaki farkları herkes biliyordur. 🧐
Biraz kod üzerinden konuşalım.✨
CronJobService
isimli bir abstract class oluşturduk ve constructor içerisinde cron ifademizi ve TimeZoneInfo bilgimizi aldık. Cronos
tam bu aşamada işimizi kolaylaştırıyor. Cronos
yardımıyla string olarak gelen değeri gerçek bir cron ifadesine dönüştürebiliyoruz. Cron ifademizi oluşturduktan sonra System.Timers
üzerinden gelen Timer
yapısını kullanarak ilgili cron ifadesinden ürettiğimiz zaman dilimi için cron işimizi schedule ediyoruz.

Timer
System.ComponentModel
inheritance alan bir sınıf. Component
sınıfının ise IDisposible
arayüzünden türediğini görüyoruz. Bu sebeple işimiz bittikten sonra timer nesnemizi dispose etmek daha scalable bir uygulama yapmamızı sağlayacaktır.
Timer yani zamanlayıcı aracılığıyla oluşturduğumuz cron ifadesinin çalışma anını yakalayabiliyoruz. Cron işini çalıştırdıktan sonra tekrarlanabilmesi için yeniden schedule etmek gerektiğini unutmayalım.

IHostedService
arayüzünü unutmayalım tabii. Uygulamamız çalıştığı anda StartAsync
yordamı çalışır ve ilgili cron işini schedule eder. StopAsync
ise tam tersi timer nesnemizi dispose ederek GC için uygun olacak şekilde serbest bırakır.
Artık CronJobService
soyut sınıfımızı kullanarak cron işlerimizi oluşturabiliriz. Endişelenmeyin bu yapıları sizin için bir kütüphane haline getirdim. 🎉 EasyCronJob
ile yapmanız gerekenler kendi cron işinizi oluşturmak ve Startup.cs
içerisinde istediğiniz cron değerini ayarlamak.
Hadi EasyCronJob
kütüphanesini yakından tanıyalım. 💡🧐
Öncelikle Nuget üzerinden EasyCronJob
kütüphanesini uygulamamıza indirelim.Install-Package EasyCronJob.Core -Version 1.0.0
Kendi cron işinizi tanımlayın. Tanımladığınız işin gövde kısmını DoWork
yordamına ekleyebilirsiniz. Ek olarak StartAsync
ve StopAsync
yordamları içine işin başladığını ve bittiğini görmek için log ekleyebilirsiniz.
Örnek olması için Console üzerine log yazan bir cron işi tanımladım.
Artık yapmamız gereken tek şey Startup.cs
içerisinde cron işimizi tanımlamak.
Tanımladığım cron ifadesinin ne anlamına geldiğini yazının başında paylaştığım crontab.guru sitesinden görebilirsiniz.
Örnekte bir tane cron işi oluşturup çalıştırdım ancak siz istediğiniz kadar cron işi tanımlayabilirsiniz. Unutmamanız gereken konu ise her bir cron işimizi Startup.cs
üzerinde tanımlamanız gerektiğidir.

Kapanış bölümünde ise neden EasyCronJob
kullanalım sorusuna yanıt oluşturmaya çalışacağım ve son olarak EasyCronJob
kütüphanesinin cyclomatic complexity değerlerini sizlerle paylaşacağım.
Ben günlük hayatımda background işler için Hangfire tercih ediyorum. Sağladığı arayüz ve database üzerinde işlerin tanımlanması benim işlerimi çok rahatlatıyor. Hatta microservice mimarisinde concurrency sorununu bile çözüyor. Hangfire üzerinde tanımladığınız işler fail olduğunda hangfire default on kere bu işi tekrar deniyor. Tabii siz isterseniz bu değeri değiştirebiliyorsunuz. Fail olan işlerinizi dashboard üzerinden tekrar çalıştırabiliyorsunuz. Yani anlayacağınız hangfire background işleri yönetmekte oldukça başarılı. Henüz paralı sürümünü kullanacak kadar zengin olmadım ama free özelliklerinin yanı sıra ücretli özellikleri de hayatımızı oldukça kolaylaştırıyor.
Tabii hiç bir üretici “benim yoğurdum ekşi demez” 😊
Bu kütüphane hangfire veya Quartz gibi advance kütüphanelerle karşılaştırılamaz. Hafta sonu projelerinde veya hızlı ve basit olmasını istediğiniz cron işlerinizde kullanabiliriniz. EasyCronJob
sadece IHostedService
üzerinden bize sağlanan iki yordamı evirip çevirip kolayca cron işlerimizi tanımlayabileceğimiz bir arayüz sunuyor.
Meraklısı için code map🗺

Meraklısı için code metrics

Source Code
https://github.com/furkandeveloper/EasyCronJob
Documentation
https://furkandeveloper.github.io/EasyCronJob/
Other
https://github.com/furkandeveloper/EasyCronJob/wiki
Eğer EasyCronJob
işinizi kolaylaştırdıysa star vererek ve arkadaşlarınızla paylaşarak destek olabilirsiniz.
Happy Coding ⌨🖱🖥
Schedule Cron Jobs using HostedService in ASP.NET Core | by Changhui Xu | codeburst
Crontab.guru — The cron schedule expression editor
Background tasks with hosted services in ASP.NET Core | Microsoft Docs