How to schedule daily email sending tasks in ASP.NET?

csharp

(afree) #1

Scheduling tasks in ASP.NET is one of the biggest concerns for ASP.NET wed developers, as it’s usually required to do some regular tasks such as Daily or Weekly mailing (newsletter…etc), regular website maintenance, regular tweeting…etc mainly it can be used to do anything you can think of that needs to be done regularly.

Scheduling tasks in windows can be done using many means including but not limited to Windows services, or scheduled batch files with the windows tasks schedule. but that is not always accessible using regular ASP.NET shared hosting services. thus this article will discuss doing that using Quartz.NET as an alternative.

Quartz.NET is an open source scheduling library for ASP.NET, you can get it using nuget. You can install Quartz.NET either by executing this command “Install-Package Quartz” using Visual Studio’s Package Manager Console prompt, or by right clicking on the project in Visual Studio’s Solution Explorer and selecting Manage Nuget Packages.

Quartz consists of three primary components:

  • A Job:
    is the task to be performed. You can define a Job by implementing its base interface IJob which has a single method named Execute(IJobExecutionContext context) where you define your actions that will be preformed whenever the Job is Called by the scheduler.

  • A Trigger:
    dictates how and when the job is executed,

  • A Scheduler:
    which takes care of ensuring that the job is performed on the schedule dictated by the trigger configuration.

To clarify the way Quartz works we will be making a sample that uses Quartz to do a very usual scenario “sending regular mails”.

First we define a Job as below:

using Quartz;
using System;
using System.Net;
using System.Net.Mail;
namespace QuartzSample
{
    public class DailyMailJob : IJob
    {
        public void Execute(IJobExecutionContext context)
        {
            using (var msg = new MailMessage("sender@gmail.com", "recipient@gmail.com"))
            {
                msg.Subject = "Sample Test Mail";
                msg.Body = "Hello world From Stopbyte.com<br><hr>Sent at: " + DateTime.Now;
                using (SmtpClient sc = new SmtpClient())
                {
                    sc.EnableSsl = true;
                    sc.Host = "smtp.gmail.com";
                    sc.Port = 587;
                    sc.Credentials = new NetworkCredential("sender@gmail.com", "your-password-here");
                    sc.Send(message);
                }
            }
        }
    }
}

Here we have defined our DailyMailJob, and The Execute Method that will be called whenever time is appropriate by Quartz Scheduler. The Execute method above all it does is sending a specific mail using SMTP client to a recipient’s gmail account.

In the next step we will be configuring the Scheduler, Trigger and the Job altogether:

using Quartz;
using Quartz.Impl;
using System;

namespace QuartzSample
{
    public class OurSampleScheduler
    {
        public static void Start()
        {
            /* STEP 1: we create a scheduler and Start it. */
            IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
            scheduler.Start();

            /* STEP 2: We create a DailyMailJob instance using Quartz JobBuilder. */
            IJobDetail job = JobBuilder.Create<DailyMailJob>().Build();

            /* STEP 3: We Create a Trigger and configure it to fire once everyday. */
            ITrigger trigger = TriggerBuilder.Create()
                .WithDailyTimeIntervalSchedule
                  (s =>
                     s.WithIntervalInHours(24)
                    .OnEveryDay()
                    .StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(0, 0))
                  )
                .Build();

            /* STEP 4: Finally we schedule our Job in the scheduler using the trigger we created above. */
            scheduler.ScheduleJob(job, trigger);
        }
    }
}

Now next thing to do is to start our Scheduler at application startup. the best place to do that would be the Global.asax file within the Application_Start event, as follows:

using System;
using System.Web;
using System.Web.Optimization;
using System.Web.Routing;

namespace QuartzSample
{
    public class Global : HttpApplication
    {
        void Application_Start(object sender, EventArgs e)
        {
            /* Any other code to be called at application startup can be added here. */

            /* Here we call the Start Method of OurSampleScheduler class.
             * Remember, Start() method is static that's why we call it without initializing
             * the class. */
            OurSampleScheduler.Start();
        }
    }
}

And that’s all you need to do to setup Quartz, and avoid messing around with Windows Tasks scheduler or your Servers internal options. Quartz.NET can be very handy.

One final note for those using limited shared hosting. sometimes shared hosting can put your website application to idle, after a small period of time if it has not activity. to avoid suc limitation. you can add another Job to your scheduler as above with smaller delay compared to the one of your hosting provider. and that Job can be used to maintain the website’s activity and keep it alive. probably doing a web request every few minutes would be perfect.



NOTE: This is a Wiki post, any member of the community is free to improve this article.


(Yassine) #2

Awesome, and really useful article, good job @afree