زمانبندی کارها با استفاده از Quartz.Net در ASP.Net

چهارشنبه 22 دی 1395

سوالی که سالها در انجمن های ASP.Net مطرح بود ، چگونگی زمانبندی کارها در Asp.Net به عنون قسمتی از برنامه وب بود . برای مثال ، شما نیاز دارید که در یک ساعت معین هر 24 ساعت یکبار ایمیلی برای کاربران ارسال شود . در این مقاله به بررسی این امر خواهیم پرداخت.

زمانبندی کارها با استفاده از Quartz.Net در ASP.Net

شما حتما با چگونگی استفاده از رویداد  Session Startدر Global.asax  برای مدیریت اصولی "زمان"  کارها آشنا هستید . 
اگرچه ، این بستگی به ترافیک وبسایت شما دارد که آیا زمان بندی نیاز دارد ، البته اگر چنین نیست ، آن در هنگام کارهای حیاتی بدون استفاده است . Quartz.Net یک کتابخانه زمانبندی  open source است که از طریق NuGet در دسترس شما میباشد .  ما در این مقاله به پیاده سازی ساده و ابتدایی که شما را در کار ایمیل ارسال کردن کمک خواهد کرد ، خواهیم پرداخت . ما در این مقاله مثال خود را با استفاده از Web Forms شرح خواهیم داد که البته استفاده از این کتابخانه در MVC و Web Pages چندان تفاوتی ندارد . 

راحت ترین و سریع ترین راه برای دسترسی به Quartz.Net  استفاده از NuGet میباشد . همچنین شما میتوانید با استفاده از وارد کردن دستور Install-Package Quartz در Package Manager Console این پکیج را به پروژه خود اضافه کنید . 
ما از روش اول استفاده می کنیم ، روی Solution پروژه کلیک راست کرده و Manage NuGet Packages را بزنید . 



پنجره جدیدی باز خواهد شد ، 'quartz' را جستجو کنید و زمانی که پکیج پیدا شد ، آن را نصب کنید . 




به همین سادگی !. 
Quartz شامل 3 مولفه اصلی  job - trigger  و یک schedular میباشد . Job همان کاری است که باید انجام شود . trigger دستور چگونگی اجرا شدن job را میدهد . و هر دوی Job و Trigger برای Schaduling ثبت میشوند که بررسی میکند که Job در زمان دستور زمانبندی داده شده با پیکربندی Trigger انجام شده است . 

Job یک کلاس است .  برای کار با این در Quartz  ، این باید اینترفیس IJob در Quartz را که دارای یک عضو هست پیاده سازی کند . متد Execute عضو IJob میباشد . این متد کاری را که باید انجام شود را تعریف میکند . به مثال زیر توجه فرمایید :

using Quartz;
using System;
using System.Net;
using System.Net.Mail;

namespace ScheduledTaskExample.ScheduledTasks
{
    public class EmailJob : IJob
    {
        public void Execute(IJobExecutionContext context)
        {
            using (var message = new MailMessage("user@gmail.com", "user@live.co.uk"))
            {
                message.Subject = "Test";
                message.Body = "Test at " + DateTime.Now;
                using (SmtpClient client = new SmtpClient
                {
                    EnableSsl = true,
                    Host = "smtp.gmail.com",
                    Port = 587,
                    Credentials = new NetworkCredential("user@gmail.com", "password")
                })
                {
                    client.Send(message);
                }
            }
        }
    }
}

متد Execute یک شی IJobExecutionContext را به عنوان پارامتر دریافت میکند . Schaduler این را زمانی که متد Execute را فراخوانی میکند ، ارسال میکند . این دارای یکسری داده های پیکربندی شده در مورد job میباشد ( که شما یه ذره قبل تر آنها را تنظیم کرده اید ) . همه ی کارهایی که در این مثال انجام میشود مربوط به ارسال ایمیل است . بدنه ی متد میتواند شامل هر چیزی باشد که شما نیاز دارید و میخواهید رخ دهد  . برای مثال ،  این میتواند یک کوئری به پایگاه داده باشد و یا ارسال ایمیل به تمام کاربرانی که در این بخش وارد شده اند . اما به خودیِ خود job هیچ کاری انجام نمیدهد . 

کدی که در قسمت بعدی مورد بررسی قرار میدهیم ، شامل یکسری تنظیمات برای Schaduler و job میباشد . در مجموع این Trigger ساخته و مقداردهی خواهد شد . 

using Quartz;
using Quartz.Impl;
using System;

namespace ScheduledTaskExample.ScheduledTasks
{
    public class JobScheduler
    {
        public static void Start()
        {
            IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
            scheduler.Start();

            IJobDetail job = JobBuilder.Create<EmailJob>().Build();

            ITrigger trigger = TriggerBuilder.Create()
                .WithDailyTimeIntervalSchedule
                  (s =>
                     s.WithIntervalInHours(24)
                    .OnEveryDay()
                    .StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(0, 0))
                  )
                .Build();

            scheduler.ScheduleJob(job, trigger);
        }
    }
}

ما در این مثال ، نام کلاس را JobScheduler میگذاریم ، اما این مهم نیست میتواند هر چیزی باشد . در حقیقت ، این حتی نیاز به این ندارد که درون یک کلاس مجزا قرار بگیرد . این کد میتواند در هر جا که شما میخواهید عمل schaduling انجام شود، قرار دهید . اساسا در یک برنامه وب ، این کد در رویداد Application_Start در Global.asax قرار خواهد گرفت . در این مثال ، اصل کد در متدی با نام Start قرار خواهد گرفت . در خط اول و دوم Schaduler ساخته میشود و شروع به کار میکند . سپس با استفاده از متد <JobBuilder.Create<T در Quartz.Net یک job ساخته میشود ، T نوع کاری است که ساخته میشود . در این مورد ، این یک نمونه از EmailJob می باشد که در مرحله قبل آن را تعریف کردیم . 

بعد ، یک trigger ساخته میشود . همانطور که پیش تر گفتیم ، trigger زمانی ساخته میشود که Job شروع به کار کرده باشد . در این مثال ، Schadule مشخص میکند که Job در نصفه شب شروع به کار کرده و هر 24 ساعت یکبار هم تکرار شود این روند . 

ITrigger trigger = TriggerBuilder.Create()
    .WithIdentity("trigger1", "group1")
    .StartNow()
    .WithSimpleSchedule(x => x
        .WithIntervalInSeconds(10)
        .RepeatForever())
    .Build();

به Trigger یک نام و یک نام گروه تخصیص میدهیم بدین صورت پیدا کردن وشناسایی آن بسیار ساده تر خواهد بود . این طوری طراحی شده است که تا اتمام زمان هر 10 ثانیه یکبار اجرا شود . Fluent API ساختن trigger و درک وظیفه ای که بر عهده آنها است را سهولت میبخشد .

در نهایت ، حال کافیست که کد را اجرا کنیم . همانطور که پیش تر بیان داشتیم ، بهترین مکان برای جای دادن این کد ها در رویداد Application-Start در فایل Global.asax میباشد . پس یک JobScheduler.Start(); به application start اضافه میکنیم :

using ScheduledTaskExample.ScheduledTasks;
using System;
using System.Web;
using System.Web.Optimization;
using System.Web.Routing;

namespace ScheduledTaskExample
{
    public class Global : HttpApplication
    {
        void Application_Start(object sender, EventArgs e)
        {
            // Code that runs on application startup
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            JobScheduler.Start();
        }
    }
}



اگر شما در برنامه ASP.Net خود نیاز به زمانبندی دارید و به تنظیمات مختلف زمانبندی در سمت سرور دسترسی ندارید ، استفاده از Quartz.Net یک راه حل فوق العاده برای این مسئله میباشد .

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید