Asp.Net’te Quartz.Net ile zamanlanmış görevler

Çalıştığım bir projede her gün düzenli olarak facebook api’dan data çekiliyor. Bunu periyodik olarak yapabilmek için Quartz.Net kütüphanesini kullanıyoruz. Bu yazıda da basitçe Quartz.Net’in bir mvc projesinde nasıl kullanılacağını anlatmak istiyorum.

Proje kodlarını buradan indirebilirsiniz.

Örnek projemizde 2 farklı görevimiz olsun. Birisinin adına X diğerine Y diyorum. X görevi facebook’dan data çekerken Y görevi ise twitter’dan çeksin.

X görevi uygulama başladığı andan itibaren her 24 saatte 1 defa sonsuza kadar çalışsın.

Y görevi ise uygulama başladıktan 1 gün sonra her yarım saatte 1 defa tekrarlasın ve 10. tekrardan sonra tamamlansın.

Öncelikle için boş bir mvc uygulaması oluşturdum. Daha sonra Nuget ile Quartz.NET kütüphanesini yükledim. Oluşturacağım sınıflar düzenli ve bir arada olsun diye projede Scheduling isminde bir klasör oluşturdum (klasörün adı önemli değil).

İlk iş X görevini tanımlamak; Scheduling klasörüne XScheduler isminde bir sınıf ekliyorum. Sınıfın ismi önemli değil, istersen iz XGorevi adını da verebilirsiniz. Yapmak istediğiniz işleri, çalıştıracağınız kodları Execute metodunun içine yazmalısınız.

using Quartz;

namespace QuartzNetTest.Scheduling
{
    public class XScheduler : IJob
    {
        public void Execute(IJobExecutionContext context)
        {
            // facebook data çekme işlemleri
        }
    }
}

Yine Scheduling klasörüne YScheduler isminde bşaka bir sınıf ekliyorum

using Quartz;

namespace QuartzNetTest.Scheduling
{
    public class YScheduler : IJob
    {
        public void Execute(IJobExecutionContext context)
        {
            //twitter data çekme işlemleri
        }
    }
}

Şimdi de bu taskları çalıştıracak bir wrapper yazıyoruz. Scheduling klasörüne SchedulerWrapper isminde bir class ekliyorum.

using Quartz;
using Quartz.Impl;
using System;

namespace QuartzNetTest.Scheduling
{
    public class SchedulerWrapper
    {
        public void RunJob()
        {
            try
            {
                ISchedulerFactory schedFact = new StdSchedulerFactory();
                IScheduler sched = schedFact.GetScheduler();
                if (!sched.IsStarted)
                    sched.Start();

                IJobDetail jobX = JobBuilder.Create<XScheduler>().WithIdentity("XScheduler", null).Build();
                ISimpleTrigger triggerX = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity("XScheduler").StartAt(DateTime.UtcNow).WithSimpleSchedule(x => x.WithIntervalInHours(24).RepeatForever()).Build();
                sched.ScheduleJob(jobX, triggerX);

                IJobDetail jobY = JobBuilder.Create<YScheduler>().WithIdentity("YScheduler", null).Build();
                ISimpleTrigger triggerY = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity("YScheduler").StartAt(DateTime.UtcNow.AddDays(1)).WithSimpleSchedule(x => x.WithIntervalInMinutes(30).WithRepeatCount(10)).Build();
                sched.ScheduleJob(jobY, triggerY);
            }
            catch (Exception ex)
            {
            }
        }
    }
}

Son olarak task’ları çalıştırmak için Global.asax dosyasını aşağıdaki gibi değiştirdim.

using QuartzNetTest.Scheduling;
using System.Web.Mvc;
using System.Web.Routing;

namespace QuartzNetTest
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            SchedulerWrapper scheduler = new SchedulerWrapper();
            scheduler.RunJob();
        }
    }
}

Proje kodlarını buradan indirebilirsiniz.

11 thoughts on “Asp.Net’te Quartz.Net ile zamanlanmış görevler

  1. şinasi aslan Reply

    yakup bey merhaba;
    ben de tam böyle birşey arıyordum. yanlız her 24 saatte bir çalışan kodu örneğin her gün saat 09:00 ve 19:00 çalıştırmak istiyorum. bunun için nasıl bir kod eklemem gereklidir. şimdiden teşekkür ederim.

    • Yakup Buğra Post authorReply

      bu kod işinize yarayabilir

      var trigger = TriggerBuilder.Create().WithIdentity(“test”, null)
      .WithDailyTimeIntervalSchedule(
      x => x.StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(9, 0))
      .EndingDailyAt(TimeOfDay.HourAndMinuteOfDay(19, 0))
      .WithIntervalInHours(10))
      .Build();

  2. YAVUZ Reply

    merhaba yakup bey,

    ben 3-5 adet görev ekleyeceğim fakat bunları farklı zamanlarda çalışmasını istiyorum bu zamanları nasıl öğrenebilirim.

    misal günde 1 defa haftada 2 defa ayda 1 defa vs. vs.

    • Yakup Buğra Post authorReply

      .WithSimpleSchedule(x => x.WithIntervalInHours(24).RepeatForever()) buradaki 24 saat yerine (24×7) saat kullanabilirsiniz.

  3. Nazım Mert Bilgi Reply

    Siteye giriş yapıldığında çalışmaya başlıyor sanırım bu kodlar,siteye hiç giriş yapılmadanda bu kodları aktif olarak çalıştırabilmek mümkün mü?

    • Yakup Buğra Post authorReply

      hayır malesef, hatta IIS’deki Application Pools’da Idle Timout duration’ı 20 dakikanın üstüne çıkarmanı tavsiye ederim. siteye 20 dk içinde giriş yapan olmazsa quartz.net de çalışmayı durduracaktır.

  4. OĞUZHAN SARI Reply

    Merhaba,
    Ben TCMB döviz kurlarını sabah 8 ve akşam 23 te çekmek istiyorum.

    Sitede gezinen biri “olmamasına” rağmen bu işlemler çalışyor mu?

    Yani her ne şekilde olursa olsun görev belirtilen zamanda çalışıyor mu?

    IIS in kapalı olması dışında :))

    • Yakup Buğra Post authorReply

      Hayır. Default ayarlarda, bir siteye(application) 20 dk içinde herhangi bir istekte bulunulmazsa IIS o uygulamayı kapatır, thread’ini sonlandırır. Bu yüzden IIS Application Pool’da idle-timeout süresini uzatmanız gerekiyor. Aşağıdaki linkten nasıl yapıldığını görebilirsiniz:

      http://aspnetfaq.com/iis7-application-pool-idle-time-out-settings/

  5. Ecenur Reply

    Merhaba, ben de program 12 saatte bir kullaniciya hatirlatma maili gondersin istiyorum nasil bir kod eklemeliyim, tesekkurler

    • Yakup Buğra Post authorReply

      ISimpleTrigger triggerX = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(“XScheduler”).StartAt(DateTime.UtcNow).WithSimpleSchedule(x => x.WithIntervalInHours(24).RepeatForever()).Build();

      satırındaki 24 yerine 12 yazmanız yeterli olur

  6. Gökhan Reply

    idle timeout sorunu bende de var. Application_Start event’inda job u çalıştırmanız gerekiyor. iis te site çalıştığı andan itibaren job’larınız başlıyor. Fakat iis siteye hiç kullanıcı girmediğinde 20 dk sonra siteyi beklemeye alıyor. Ve job lar duruyor. Bunun önüne geçmek için,

    10 – 15 dk da bir sürekli çalışan bir job daha yapmanız gerekiyor. Adı PingMySelf olsun.

    var webClient = new WebClient();
    webClient.DownloadString(“http://www.siteadi.com”);//yada ip adresiniz
    webClient.Dispose();

    Yukarıdakinin görevinden bahsetmeme gerek yok heralde. Yukardaki kod ile sitenize client olarak erişmiş oluyorsunuz. Bu sayede iis sitede kullanıcı olduğunu sanıyor ve iddle timeout süresini sıfırlıyor. 20dk daha süreniz oldu. İsterseniz süreyi 19dk da bir çalışacak şekle getirebilirsiniz. Yada isterseniz 10dk da bir benim gibi kullanabilirsiniz.

Leave a Reply

Your email address will not be published. Required fields are marked *