Quartz.Net Scheduler Listeners, Part 2 of Quartz.Net Listeners in Detail

This is the second post in the Quartz.Net Listener Tutorial series. It’s also the second part of the introduction to listeners overview series. You can find Part 1 here. Today we’ll be looking at scheduler listeners and how to implement one.

As we mentioned in Part 1, scheduler listeners get notified of high level scheduler events. To implement a scheduler listener, you need to implement the ISchedulerListener interface. Here’s what that interface looks like:

public interface ISchedulerListener
{
    void JobScheduled(ITrigger trigger);
    void JobUnscheduled(TriggerKey triggerKey);
    void TriggerFinalized(ITrigger trigger);
    void TriggerPaused(TriggerKey triggerKey);
    void TriggersPaused(string triggerGroup);
    void TriggerResumed(TriggerKey triggerKey);
    void TriggersResumed(string triggerGroup);
    void JobAdded(IJobDetail jobDetail);
    void JobDeleted(JobKey jobKey);
    void JobPaused(JobKey jobKey);
    void JobsPaused(string jobGroup);
    void JobResumed(JobKey jobKey);
    void JobsResumed(string jobGroup);
    void SchedulerError(string msg, SchedulerException cause);
    void SchedulerInStandbyMode();
    void SchedulerStarted();
    void SchedulerStarting();
    void SchedulerShutdown();
    void SchedulerShuttingdown();
    void SchedulingDataCleared();
}

 

In a nutshell, those are the scheduler level events that you can get notifications for. Let’s go ahead and make a simple implementation of the scheduler listener. You can download the sample code from the Quartz.Net ebook samples. Open the

QuartzNetBookSamples solution and look for the SchedulerListenerExample.cs file, inside of the Examples project. You’ll see that all we have is a simple implementation that writes a message to the console when one of the events is triggered. The messages are in this format: The scheduler called {methodName}. Here’s what the source code for that looks like:

using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Examples { public class SchedulerListenerExample : ISchedulerListener {

    public void JobAdded(IJobDetail jobDetail)
    {
        Console.WriteLine("The scheduler called {0}", MethodBase.GetCurrentMethod().Name);
    }

    public void JobDeleted(JobKey jobKey)
    {
        Console.WriteLine("The scheduler called {0}", MethodBase.GetCurrentMethod().Name);
    }

    public void JobPaused(JobKey jobKey)
    {
        Console.WriteLine("The scheduler called {0}", MethodBase.GetCurrentMethod().Name);
    }

    public void JobResumed(JobKey jobKey)
    {
        Console.WriteLine("The scheduler called {0}", MethodBase.GetCurrentMethod().Name);
    }

    public void JobScheduled(ITrigger trigger)
    {
        Console.WriteLine("The scheduler called {0}", MethodBase.GetCurrentMethod().Name);
    }

    public void JobUnscheduled(TriggerKey triggerKey)
    {
        Console.WriteLine("The scheduler called {0}", MethodBase.GetCurrentMethod().Name);
    }

    public void JobsPaused(string jobGroup)
    {
        Console.WriteLine("The scheduler called {0}", MethodBase.GetCurrentMethod().Name);
    }

    public void JobsResumed(string jobGroup)
    {
        Console.WriteLine("The scheduler called {0}", MethodBase.GetCurrentMethod().Name);
    }

    public void SchedulerError(string msg, SchedulerException cause)
    {
        Console.WriteLine("The scheduler called {0}", MethodBase.GetCurrentMethod().Name);
    }

    public void SchedulerInStandbyMode()
    {
        Console.WriteLine("The scheduler called {0}", MethodBase.GetCurrentMethod().Name);
    }

    public void SchedulerShutdown()
    {
        Console.WriteLine("The scheduler called {0}", MethodBase.GetCurrentMethod().Name);
    }

    public void SchedulerShuttingdown()
    {
        Console.WriteLine("The scheduler called {0}", MethodBase.GetCurrentMethod().Name);
    }

    public void SchedulerStarted()
    {
        Console.WriteLine("The scheduler called {0}", MethodBase.GetCurrentMethod().Name);
    }

    public void SchedulerStarting()
    {
        Console.WriteLine("The scheduler called {0}", MethodBase.GetCurrentMethod().Name);
    }

    public void SchedulingDataCleared()
    {
        Console.WriteLine("The scheduler called {0}", MethodBase.GetCurrentMethod().Name);
    }

    public void TriggerFinalized(ITrigger trigger)
    {
        Console.WriteLine("The scheduler called {0}", MethodBase.GetCurrentMethod().Name);
    }

    public void TriggerPaused(TriggerKey triggerKey)
    {
        Console.WriteLine("The scheduler called {0}", MethodBase.GetCurrentMethod().Name);
    }

    public void TriggerResumed(TriggerKey triggerKey)
    {
        Console.WriteLine("The scheduler called {0}", MethodBase.GetCurrentMethod().Name);
    }

    public void TriggersPaused(string triggerGroup)
    {
        Console.WriteLine("The scheduler called {0}", MethodBase.GetCurrentMethod().Name);
    }

    public void TriggersResumed(string triggerGroup)
    {
        Console.WriteLine("The scheduler called {0}", MethodBase.GetCurrentMethod().Name);
    }
}

}

 

 

And if you set the EmbeddedScheduler project as your startup project and press F5, you should see output similar to this:

The scheduler called SchedulerStarting
The scheduler called JobAdded
The scheduler called JobScheduled
The scheduler called JobAdded
The scheduler called JobScheduled
The scheduler called JobUnscheduled
The scheduler called JobScheduled
The scheduler called JobUnscheduled
The scheduler called JobScheduled
The scheduler called SchedulerStarted
IsStarted=True
SchedulerInstanceId=NON_CLUSTERED
SchedulerName=ServerScheduler
The scheduler is running. Press any key to stop
The scheduler called TriggerFinalized
The scheduler called JobDeleted
Shutting down scheduler
The scheduler called SchedulerInStandbyMode
The scheduler called SchedulerShuttingdown
The scheduler called SchedulerShutdown
IsShutdown=True
The scheduler has been shutdown.

 

If you look at the output, you’ll notice that several of the scheduler’s events were raised and so our listener was notified of them. Lines 1-10, 14-16 and 18-20 were all generated in the listener.

I’d like to call out some not-so-obvious events being raised by the scheduler. Notice that you can add and schedule jobs even before the scheduler starts. Also notice that when shutting the scheduler down, the scheduler gets set to standby mode (line 18).

I think that’s it for scheduler listeners. Next, we’ll be looking at implementing a job listener.