How to use Quartz.net with ASP.NET

asp.netquartz.net

asp.net Problem Overview


I don't know how to use Quartz.dll in ASP.NET. Where to write the code for scheduling jobs to trigger mail every morning? Please if some body knows about it plz help me...

Edit: I found HOW TO use Quartz.NET in PRO way? to be really useful.

asp.net Solutions


Solution 1 - asp.net

You have a couple of options, depending on what you want to do and how you want to set it up. For example, you can install a Quartz.Net server as a standalone windows serviceor you can also embed it inside your asp.net application.

If you want to run it embedded, then you can start the server from say your global.asax, like this (from the source code examples, example #12):

NameValueCollection properties = new NameValueCollection();
properties["quartz.scheduler.instanceName"] = "RemoteServer";

// set thread pool info
properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
properties["quartz.threadPool.threadCount"] = "5";
properties["quartz.threadPool.threadPriority"] = "Normal";

ISchedulerFactory sf = new StdSchedulerFactory(properties);
IScheduler sched = sf.GetScheduler();
sched.Start();

If you run it as a service, you would connect remotely to it like this (from example #12):

NameValueCollection properties = new NameValueCollection();
properties["quartz.scheduler.instanceName"] = "RemoteClient";

// set thread pool info
properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
properties["quartz.threadPool.threadCount"] = "5";
properties["quartz.threadPool.threadPriority"] = "Normal";

// set remoting expoter
properties["quartz.scheduler.proxy"] = "true";
properties["quartz.scheduler.proxy.address"] = "tcp://localhost:555/QuartzScheduler";
// First we must get a reference to a scheduler
ISchedulerFactory sf = new StdSchedulerFactory(properties);
IScheduler sched = sf.GetScheduler();
		

Once you have a reference to the scheduler (be it via remoting or because you have an embedded instance) you can schedule jobs like this:

// define the job and ask it to run
JobDetail job = new JobDetail("remotelyAddedJob", "default", typeof(SimpleJob));
JobDataMap map = new JobDataMap();
map.Put("msg", "Your remotely added job has executed!");
job.JobDataMap = map;
CronTrigger trigger = new CronTrigger("remotelyAddedTrigger", "default", "remotelyAddedJob", "default", DateTime.UtcNow, null, "/5 * * ? * *");
// schedule the job
sched.ScheduleJob(job, trigger);

Here's a link to some posts I wrote for people getting started with Quartz.Net: http://jvilalta.blogspot.com/2009/03/getting-started-with-quartznet-part-1.html

Solution 2 - asp.net

A few weeks ago I wrote about using Quartz.Net to schedule jobs in Windows Azure Worker Roles. Since then I ran into a requirement that pushed me to create a wrapper around the Quartz.Net IScheduler. The JobSchedule has the responsibility of reading a schedule string from the CloudConfigurationManager and schedule a job.

The CloudConfigurationManager reads settings from the Role’s configuration file, which can be edited through the Windows Azure Management Portal under the configure section of your cloud services.

The following example will schedule a job which needs to be executed everyday at 6 AM, 8 AM, 10 AM, 12:30 PM and at 4:30 PM. The schedule is defined in the Role settings which can be edited through Visual Studio. To reach the Role settings, go to your Windows Azure Cloud Service project and find the desired Role configurations under the Role folder. Open the configuration editor by double clicking on the configuration file, then navigate to the ‘Settings’ tab. Click on ‘Add Setting’ and name the new setting ‘JobDailySchedule’ and set its value to 6:0;8:0;10:0;12:30;16:30;

The code from this Post is part of the Brisebois.WindowsAzure NuGet Package

To install Brisebois.WindowsAzure, run the following command in the Package Manager Console

PM> Install-Package Brisebois.WindowsAzure

Get more details about the Nuget Package.

Then using the JobSchedule schedule a daily job using the schedule defined in the Role’s configuration file.

var schedule = new JobSchedule();

schedule.ScheduleDailyJob("JobDailySchedule",
                            typeof(DailyJob));

The DailyJob implementation goes as follows. Since this is a demo, I will not add any specific logic to the job.

public class DailyJob : IJob
{
    public void Execute(IJobExecutionContext context)
    {
        //Do your daily work here
    }
}

The JobSchedule wraps the Quartz.Net IScheduler. In a previous post I spoke about the importance of wrapping your 3rd party tools, this is an excellent example because I am containing the job scheduling logic and I could potentially change this logic without affecting the code that is using the JobSchedule.

The JobSchedule should be configured when the Role starts and the JobSchedule instance should be maintained throughout the Role’s lifetime. Changing the schedule can be achieved by changing the ‘JobDailySchedule’ setting through the Windows Azure Management Portal under the configure section of your cloud services. Then to apply the new schedule, restart the Role instance through the Windows Azure Management Portal under the instances section of your cloud services.

public class JobSchedule
{
    private readonly IScheduler sched;

    public JobSchedule()
    {
        var schedFact = new StdSchedulerFactory();

        sched = schedFact.GetScheduler();
        sched.Start();
    }

    /// <summary>
    /// Will schedule jobs in Eastern Standard Time
    /// </summary>
    /// <param name="scheduleConfig">Setting Key from your CloudConfigurations, 
    ///                              value format "hh:mm;hh:mm;"</param>
    /// <param name="jobType">must inherit from IJob</param>
    public void ScheduleDailyJob(string scheduleConfig, 
                                 Type jobType)
    {
        ScheduleDailyJob(scheduleConfig, 
                         jobType, 
                         "Eastern Standard Time");
    }

    /// <param name="scheduleConfig">Setting Key from your CloudConfigurations, 
    ///                              value format "hh:mm;hh:mm;"</param>
    /// <param name="jobType">must inherit from IJob</param>
    public void ScheduleDailyJob(string scheduleConfig, 
                                 Type jobType, 
                                 string timeZoneId)
    {
        var schedule = CloudConfigurationManager.GetSetting(scheduleConfig);
        if (schedule == "-")
            return;

        schedule.Split(';')
                .Where(s => !string.IsNullOrWhiteSpace(s))
                .ToList()
                .ForEach(h =>
        {
            var index = h.IndexOf(':');
            var hour = h.Substring(0, index);
            var minutes = h.Substring(index + 1, h.Length - (index + 1));

            var job = new JobDetailImpl(jobType.Name + hour + minutes, null,
                                        jobType);

            var dh = Convert.ToInt32(hour, CultureInfo.InvariantCulture);
            var dhm = Convert.ToInt32(minutes, CultureInfo.InvariantCulture);
            var tz = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);

            var cronScheduleBuilder = CronScheduleBuilder
                                            .DailyAtHourAndMinute(dh, dhm)
                                            .InTimeZone(tz);
            var trigger = TriggerBuilder.Create()
                                        .StartNow()
                                        .WithSchedule(cronScheduleBuilder)
                                        .Build();

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

    /// <summary>
    /// Will schedule jobs in Eastern Standard Time
    /// </summary>
    /// <param name="scheduleConfig">Setting Key from your CloudConfigurations, 
    ///                              value format "hh:mm;hh:mm;"</param>
    /// <param name="jobType">must inherit from IJob</param>
    public void ScheduleWeeklyJob(string scheduleConfig, 
                                  Type jobType)
    {
        ScheduleWeeklyJob(scheduleConfig, 
                          jobType, 
                          "Eastern Standard Time");
    }


    /// <param name="scheduleConfig">Setting Key from your CloudConfigurations,
    ///                              value format "hh:mm;hh:mm;"</param>
    /// <param name="jobType">must inherit from IJob</param>
    public void ScheduleWeeklyJob(string scheduleConfig, 
                                  Type jobType, 
                                  string timeZoneId)
    {
        var schedule = CloudConfigurationManager.GetSetting(scheduleConfig);

        schedule.Split(';')
                .Where(s => !string.IsNullOrWhiteSpace(s))
                .ToList()
                .ForEach(h =>
        {
            var index = h.IndexOf(':');
            var hour = h.Substring(0, index);
            var minutes = h.Substring(index + 1, h.Length - (index + 1));

            var job = new JobDetailImpl(jobType.Name + hour + minutes, null,
                                        jobType);

            var dh = Convert.ToInt32(hour, CultureInfo.InvariantCulture);
            var dhm = Convert.ToInt32(minutes, CultureInfo.InvariantCulture);
            var tz = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
            var builder = CronScheduleBuilder
                            .WeeklyOnDayAndHourAndMinute(DayOfWeek.Monday, 
                                                         dh, 
                                                         dhm)
                            .InTimeZone(tz);

            var trigger = TriggerBuilder.Create()
                                        .StartNow()
                                        .WithSchedule(builder)
                                        .Build();

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionACPView Question on Stackoverflow
Solution 1 - asp.netjvilaltaView Answer on Stackoverflow
Solution 2 - asp.netSagar KuteView Answer on Stackoverflow