NOTE: I'm now blogging at http://jayvilalta.com/blog and not updating this blog anymore. For information on the latest version of Quartz.Net, visit me there.
In case you didn’t know it yet, development of Quart.Net is moving from Sourceforge to Github. If you want to follow development of the latest version of Quartz.Net. be sure and check out the project on Github. This should make it easier for everybody to contribute any changes to the project.
Saturday, January 15, 2011
Tuesday, November 9, 2010
Quartz.Net GUI Tour - Part 2
NOTE: I'm now blogging at http://jayvilalta.com/blog and not updating this blog anymore. For information on the latest version of Quartz.Net, visit me there.
This is the second part of the Quartz.Net GUI Tour. The first part of the tour covered connecting to schedulers and adding jobs. In this post, I’ll go over the remaining features.

Clicking on the button will cause the job to be scheduled to execute once, immediately.


This concludes the quick tour of the Quartz.Net manager features. I hope you have found it useful.
This is the second part of the Quartz.Net GUI Tour. The first part of the tour covered connecting to schedulers and adding jobs. In this post, I’ll go over the remaining features.
Running Jobs
To run a job immediately, select the job from the left tree. The job details will be displayed on the right, and the run button will be enabled, as in the attached screenshot:Clicking on the button will cause the job to be scheduled to execute once, immediately.
Deleting Jobs
To delete a job, select it from the left tree. The delete button will then become enabled. Click the delete button on the right to delete the job and all of its associated triggers.Pausing and Resuming Triggers
Quartz.Net manager allows you to pause and resume triggers as well. To enable the pause / resume button, you must first select a trigger from the tree on the left. Once a trigger is selected, the pause button will be enabled. Click on the pause button to pause a trigger. If the trigger you selected is already paused, the button will say Resume instead of Pause. Click on the resume button to reactivate the selected trigger.Backup To File
The last feature we’ll discuss in the tour is the backup to file feature. This feature lets you backup all of your jobs and triggers to a text (xml) file. This file can be then be used by the xml plugin to load all the job information into, say, a new scheduler instance. To create a backup of your scheduler, right click on the entry for the scheduler in the tree. Select the backup option and enter a file name for your backup file.This concludes the quick tour of the Quartz.Net manager features. I hope you have found it useful.
Monday, November 8, 2010
Quartz.Net GUI Tour
NOTE: I'm now blogging at http://jayvilalta.com/blog and not updating this blog anymore. For information on the latest version of Quartz.Net, visit me there.
In this post I will do a quick walkthrough of the Quartz.Net GUI that we open sourced last week.

Type in your server name, and change any of the default connection information if necessary. Once connected, your screen should look something like this:


Now, select a job type from the dropdown and fill out all the boxes with the necessary information. You do not need to add job data unless your job requires it. If your job requires job data to be set, use the right hand side of the dialog to add as many key value pairs of data as needed.
Once you have set up your data, click on add and your job will be scheduled. The dialog will close and the Scheduler objects pane will show the job that you scheduled.
In this post I will do a quick walkthrough of the Quartz.Net GUI that we open sourced last week.
Installation
We do not have an installer right now, so your options are:- 1. Download the source code and hit F5.
- 2. After having downloaded the source code and done a successful build, run the executable.
- 3. Download the binaries, extract them into a folder and run the executable.
Connecting to a Scheduler
Click on Scheduler –> Connect. You should get the following connection dialog:Type in your server name, and change any of the default connection information if necessary. Once connected, your screen should look something like this:
Adding Custom Jobs to the Manager
Before we can add a custom job, we must first tell the application which dlls contain the jobs that we want to add. Adding dlls to the list of scanned dlls is done by editing the JobAssemblies.txt file. Just include the name of your dll in the file, by adding it to the bottom of the list.Adding a Job to the Scheduler
To add or schedule a job on the scheduler that you are connected to, click on the Jobs –> Add menu. You should get a dialog box like this:Now, select a job type from the dropdown and fill out all the boxes with the necessary information. You do not need to add job data unless your job requires it. If your job requires job data to be set, use the right hand side of the dialog to add as many key value pairs of data as needed.
Once you have set up your data, click on add and your job will be scheduled. The dialog will close and the Scheduler objects pane will show the job that you scheduled.
What About the Run, Pause, Delete and Edit Buttons?
Part 2 of the tour is now available, with a quick description on how to use these buttons.Monday, November 1, 2010
Open Source Graphical User Interface (GUI) for Quartz.Net
NOTE: I'm now blogging at http://jayvilalta.com/blog and not updating this blog anymore. For information on the latest version of Quartz.Net, visit me there.
Click Forensics, the company I work for, has graciously allowed me to open source the code to a GUI for Quartz.net. The latest code is currently available on github. We have been using Quartz.net for over a year and we use this tool to manage our schedulers. The application is written in C#, using windows forms and is targeting .Net 4.0
The code should be considered alpha quality at this point, as some features are missing and some don’t work properly. The documentation is pretty much non-existent at this point, but as I have some spare time I will post updates here and on github. Please give it a try send us any feedback you might have.
I would suggest you download the source and build it yourself, but for your convenience, you can download the binaries from https://github.com/adometry/QuartzNetManager/downloads.
Click Forensics, the company I work for, has graciously allowed me to open source the code to a GUI for Quartz.net. The latest code is currently available on github. We have been using Quartz.net for over a year and we use this tool to manage our schedulers. The application is written in C#, using windows forms and is targeting .Net 4.0
The code should be considered alpha quality at this point, as some features are missing and some don’t work properly. The documentation is pretty much non-existent at this point, but as I have some spare time I will post updates here and on github. Please give it a try send us any feedback you might have.
I would suggest you download the source and build it yourself, but for your convenience, you can download the binaries from https://github.com/adometry/QuartzNetManager/downloads.
Creating a Quartz.Net JobListener
NOTE: I'm now blogging at http://jayvilalta.com/blog and not updating this blog anymore. For information on the latest version of Quartz.Net, visit me there.
This post will describe how to create a Quartz.Net job listener. As an example, we will write a job history listener that will log job start and end times to a database.
For the task at hand, we will not implement JobExecutionVetoed, since we just want to be notified when a job starts and when it ends. Since we want to log start and end times for our jobs, we will focus on implementing the JobToBeExecuted and the JobWasExecuted methods.
In this method, we will write a record to the database, indicating that the job has started processing. Your implementation of the method could look something like this:
Basically we are inserting a row into a table with all the information we need in order to be able to determine the job’s run time. One thing you should note is that we are creating a GUID and sticking it into the context. This is so that we can record when the job finishes running.
This method gets called whenever the job finishes running. The only thing left to do now is to update the row we inserted when the job began running and set the end time. Here is what that method might look like:
As you can see here, we are reaching into the context and extracting the GUID that we put there when the job started running. This will allow us to update the correct row and thus be able to calculate how long it took the job to finish running.
Now that you have written a job listener. You have a couple of choices:
I hope this post was useful.
This post will describe how to create a Quartz.Net job listener. As an example, we will write a job history listener that will log job start and end times to a database.
Creating the Job Listener
To create a job listener, we need to implement the IJobListener interface. Here is the interface:public interface IJobListener{string Name { get; }void JobExecutionVetoed(JobExecutionContext context);
void JobToBeExecuted(JobExecutionContext context);
void JobWasExecuted(JobExecutionContext context, JobExecutionException jobException);
}
For the task at hand, we will not implement JobExecutionVetoed, since we just want to be notified when a job starts and when it ends. Since we want to log start and end times for our jobs, we will focus on implementing the JobToBeExecuted and the JobWasExecuted methods.
Implementing the JobToBeExecuted Method
In this method, we will write a record to the database, indicating that the job has started processing. Your implementation of the method could look something like this:
Guid historyId = Guid.NewGuid();context.JobDetail.JobDataMap.Add("historyID", historyId);
string sql = @"INSERT INTO [dbo].[QRTZ_JOB_HISTORY]([JobHistoryID],[JobName],[StartDate],[Server],[JobType]) VALUES(@JobHistoryID,@JobName,@StartDate,@Server,@JobType)";using (SqlConnection connection = new SqlConnection(connectionStringGoesHere){connection.Open();using (SqlCommand command = new SqlCommand(sql, connection)){command.Parameters.AddWithValue("@JobHistoryID", historyId);
command.Parameters.AddWithValue("@JobName", context.JobDetail.Name);
command.Parameters.AddWithValue("@StartDate", DateTime.Now);
command.Parameters.AddWithValue("@Server", Environment.MachineName);
command.Parameters.AddWithValue("@JobType", context.JobDetail.JobType.ToString());
command.ExecuteNonQuery();}}
Basically we are inserting a row into a table with all the information we need in order to be able to determine the job’s run time. One thing you should note is that we are creating a GUID and sticking it into the context. This is so that we can record when the job finishes running.
Implementing the JobWasExecuted Method
This method gets called whenever the job finishes running. The only thing left to do now is to update the row we inserted when the job began running and set the end time. Here is what that method might look like:
string sql = "UPDATE [dbo].[QRTZ_JOB_HISTORY] SET [EndDate]=@EndDate WHERE [JobHistoryID]=@JobHistoryID";using (SqlConnection connection = new SqlConnection(connectionStringGoesHere)){connection.Open();using (SqlCommand command = new SqlCommand(sql, connection)){command.Parameters.AddWithValue("@JobHistoryID", (Guid)jobDetail.JobDataMap.Get("historyID"));command.Parameters.AddWithValue("@EndDate", DateTime.Now);
command.ExecuteNonQuery();}}
As you can see here, we are reaching into the context and extracting the GUID that we put there when the job started running. This will allow us to update the correct row and thus be able to calculate how long it took the job to finish running.
Wrapping Up
Now that you have written a job listener. You have a couple of choices:
- You can add the listener directly to your job, in which case only jobs that have the listener attached will log their execution in our database.
- Add the listener as a global listener. Global listeners get called whenever any job runs, and our history listener seems like a good candidate for becoming a global listener. My previous post describes how to schedule a global listener.
I hope this post was useful.
Wednesday, September 8, 2010
Creating A Quartz.Net Plug-in
NOTE: I'm now blogging at http://jayvilalta.com/blog and not updating this blog anymore. For information on the latest version of Quartz.Net, visit me there.
In this post I’ll walk you through creating and configuring a Quartz.Net plug-in. It’s not very complicated, but this will depend on what you are trying to do with your plug-in. For the example we will create a plug-in that attaches a global job listener to the quartz scheduler. This will come in handy later on, since I will be posting another article describing how to create a job listener for Quartz.Net. The Quartz.net source code also includes an example of how to do this in the LoggingJobHistoryPlugin.
Why do we need to create a plug-in to register a global job listener? Global job listeners are not stored in the job store, so they need to be added to the scheduler every time it starts. That’s why we’re going with the global job listener / plug-in combo.
This interface has 3 methods that we could implement. Let’s look at these methods in a little more detail.
The comments in the code say that this method is “Called during creation of the IScheduler in order to give the ISchedulerPlugin a chance to initialize. At this point, the Scheduler's IJobStore is not yet (ready?). If you need direct access (to) your plug-in, you can have it explicitly put a reference to itself in the IScheduler's SchedulerContext Initialize(string, IScheduler) method”. We’re just adding a global listener to the scheduler, so we’ll include the code to do this in the Initialize method. Alternatively, we could move this code to the Start method and the result would be the same.
The comments in the code say that this method is called when the associated IScheduler is started, in order to let the plug-in know it can now make calls into the scheduler if it needs to. We’re not going to be making any calls into the scheduler, so there is no need to implement this method.
For this method the code comments say that it is called in order to inform the ISchedulerPlugin that it should free up all of it's resources because the scheduler is shutting down. We don’t have any resources to free up, so we aren’t going to implement this method either.
Now, let’s take a look at the code for the plug-in. We’re doing something pretty simple here, so the implementation is very short.
Yes, that’s all there is to creating a very simple plug-in. We’re not entirely done though, since now we need to tell the scheduler to load the load the plug-in upon startup.
The last step is to let the scheduler know that it needs to load your plug-in upon start. This is done via the configuration file, by setting a property as follows:
Let’s look at all the components of this property in detail. First there is quartz.plugin, which tells the scheduler that this is a plug-in that needs to be loaded. The {name} portion is the name that you want to give to your plug-in, and is the name that is passed in to the Initialize method above. The value of the property indicates the Type of the plug-in, so that the scheduler can load it into memory. {type name} is the full name of your plug-in, which in our case would be something.something.JobListener. {assembly name} is the name of your assembly file, minus the .dll extension.
Once you add your configuration information, you are done. Make sure that your dll is in the same folder as the Quartz.Net binaries and that should be all you need to do.
In my next post we’ll tackle the implementation of the JobListener that we used as an example in this post.
In this post I’ll walk you through creating and configuring a Quartz.Net plug-in. It’s not very complicated, but this will depend on what you are trying to do with your plug-in. For the example we will create a plug-in that attaches a global job listener to the quartz scheduler. This will come in handy later on, since I will be posting another article describing how to create a job listener for Quartz.Net. The Quartz.net source code also includes an example of how to do this in the LoggingJobHistoryPlugin.
Why do we need to create a plug-in to register a global job listener? Global job listeners are not stored in the job store, so they need to be added to the scheduler every time it starts. That’s why we’re going with the global job listener / plug-in combo.
The Plug-in Interface
To create the plug-in we need to implement the ISchedulerPlugin interface. Here is the ISchedulerPlugin interface:public interface ISchedulerPlugin{void Initialize(string pluginName, IScheduler sched);void Start();
void Shutdown();
}
This interface has 3 methods that we could implement. Let’s look at these methods in a little more detail.
The Initialize method
The comments in the code say that this method is “Called during creation of the IScheduler in order to give the ISchedulerPlugin a chance to initialize. At this point, the Scheduler's IJobStore is not yet (ready?). If you need direct access (to) your plug-in, you can have it explicitly put a reference to itself in the IScheduler's SchedulerContext Initialize(string, IScheduler) method”. We’re just adding a global listener to the scheduler, so we’ll include the code to do this in the Initialize method. Alternatively, we could move this code to the Start method and the result would be the same.
The Start Method
The comments in the code say that this method is called when the associated IScheduler is started, in order to let the plug-in know it can now make calls into the scheduler if it needs to. We’re not going to be making any calls into the scheduler, so there is no need to implement this method.
The Shutdown Method
For this method the code comments say that it is called in order to inform the ISchedulerPlugin that it should free up all of it's resources because the scheduler is shutting down. We don’t have any resources to free up, so we aren’t going to implement this method either.
Creating the Plug-In
Now, let’s take a look at the code for the plug-in. We’re doing something pretty simple here, so the implementation is very short.
public void Initialize(string pluginName, IScheduler sched){sched.AddGlobalJobListener(new JobListener());
}
Yes, that’s all there is to creating a very simple plug-in. We’re not entirely done though, since now we need to tell the scheduler to load the load the plug-in upon startup.
Configuring the Scheduler to Load the Plug-In
The last step is to let the scheduler know that it needs to load your plug-in upon start. This is done via the configuration file, by setting a property as follows:
quartz.plugin.{name}.type = {type name}, {assembly name}
Let’s look at all the components of this property in detail. First there is quartz.plugin, which tells the scheduler that this is a plug-in that needs to be loaded. The {name} portion is the name that you want to give to your plug-in, and is the name that is passed in to the Initialize method above. The value of the property indicates the Type of the plug-in, so that the scheduler can load it into memory. {type name} is the full name of your plug-in, which in our case would be something.something.JobListener. {assembly name} is the name of your assembly file, minus the .dll extension.
Once you add your configuration information, you are done. Make sure that your dll is in the same folder as the Quartz.Net binaries and that should be all you need to do.
In my next post we’ll tackle the implementation of the JobListener that we used as an example in this post.
Tuesday, June 1, 2010
Running Quartz.Net 1.0.2 on .Net 4.0
NOTE: I'm now blogging at http://jayvilalta.com/blog and not updating this blog anymore. For information on the latest version of Quartz.Net, visit me there.
We recently upgraded one of our application to .Net 4.0. As part of this upgrade, we also upgraded out Quartz.net jobs to run on the 4.0 version of the .Net framework. The process was fairly straightforward, but not without surprises, so I figured I would post it here in case it’s useful. I hope that there will be an official 4.0 release made soon, so I have only included the steps of the process I followed in this post. If there’s enough interest I can upload the updates solution file. If you want to try it out for yourself, I’ve broken the process down into simple steps. Feel free to skip over the steps that are familiar to you.
1. Fix the errors, which are basically documentation errors. You’ll have to look at each of the individual errors to fix them, so I won’t describe the process in detail. Just keep pressing F8 until you’ve fixed them all.
2. Turn off warnings as errors. This is the path of least resistance.
At this point, whether you selected option 1 or 2, you should have a working build. By default, the results of the build are put under the build\2.0 folder:
Since I already have a working scheduler and didn’t want to risk screwing it up, I changed the name of the scheduler in the installer file so that I could install it side by side with my existing scheduler to be able to test it. I also changed the version numbers in case for some reason the dlls got mixed up. To change the service name, open Configuration.cs file. It’s under the Quartz.Server.Core project. Change these lines as follows (or use your imagination):
This will let you install the updated scheduler side by side with the old scheduler.
To update the version number you will have to right click on each project, select properties and then under the application tab, click on the Assembly Information button to update it:
Then just, update it to the version number of your preference. Something like this:
You should be ready to use Quartz.Net with the 4.0 framework now. If you’re going to install Quartz.net as a service, then take a look at this post. The steps you need to follow will be identical, just remember to use the new files you just built. If you are running Quartz.net embedded in your application, then update your references so they point to the new dlls.
We recently upgraded one of our application to .Net 4.0. As part of this upgrade, we also upgraded out Quartz.net jobs to run on the 4.0 version of the .Net framework. The process was fairly straightforward, but not without surprises, so I figured I would post it here in case it’s useful. I hope that there will be an official 4.0 release made soon, so I have only included the steps of the process I followed in this post. If there’s enough interest I can upload the updates solution file. If you want to try it out for yourself, I’ve broken the process down into simple steps. Feel free to skip over the steps that are familiar to you.
Step 1 – Downloading the Source Code
First, I downloaded the source code from sourceforge using subversion. The subversion url for the project is: https://quartznet.svn.sourceforge.net/svnroot/quartznet. If you’re using TortoiseSVN, then you just have to right click on the folder you want to download the source to, and then select SVN Checkout. Paste the URL above into the box and select OK. Here’s a screenshot of what I’m talking about:Step 2 – Convert the Solution File
Next locate the main solution file for the maintenance release (this is the branch I used, since it corresponds to the latest released version). The file is called Quartz.2008.sln and is located under branches –> Quartz-1.0-Maintenance. Open this file in VS2010 (right click, select open with… VS2010) and run through the upgrade wizard. Once that’s done, there are some small changes to be made.Step 3. – Target .Net 4.0
This is the tedious part… you’ll have to right click on each project, select properties and then under the Applications tab, select the new target framework:Step 4 – Fix the Build
If you build the solution now, you’ll get some warnings are errors. You have 2 options:1. Fix the errors, which are basically documentation errors. You’ll have to look at each of the individual errors to fix them, so I won’t describe the process in detail. Just keep pressing F8 until you’ve fixed them all.
2. Turn off warnings as errors. This is the path of least resistance.
At this point, whether you selected option 1 or 2, you should have a working build. By default, the results of the build are put under the build\2.0 folder:
Step 5 – Fix the Version Number and Service Name
Note: this part is optional…Since I already have a working scheduler and didn’t want to risk screwing it up, I changed the name of the scheduler in the installer file so that I could install it side by side with my existing scheduler to be able to test it. I also changed the version numbers in case for some reason the dlls got mixed up. To change the service name, open Configuration.cs file. It’s under the Quartz.Server.Core project. Change these lines as follows (or use your imagination):
private const string DefaultServiceName = "QuartzServerForNet4";private const string DefaultServiceDisplayName = "Quartz Server For Net4";private const string DefaultServiceDescription = "Quartz Job Scheduling Server For Net4";
This will let you install the updated scheduler side by side with the old scheduler.
To update the version number you will have to right click on each project, select properties and then under the application tab, click on the Assembly Information button to update it:
Then just, update it to the version number of your preference. Something like this:
Step 6 – Final Steps
You should be ready to use Quartz.Net with the 4.0 framework now. If you’re going to install Quartz.net as a service, then take a look at this post. The steps you need to follow will be identical, just remember to use the new files you just built. If you are running Quartz.net embedded in your application, then update your references so they point to the new dlls.
Labels:
quartz.net
Subscribe to:
Posts (Atom)