Monday, October 20, 2008

SharePoint: Creating Timer Jobs

Its been quiet some time since my last post. Been hectic at work lately, finally some relief. Today, I want to discuss how to create timer jobs in SharePoint.  A timer job is a schedule of when to run a service by using the SharePoint Timer service.
SharePoint Service Timer service is a service that runs other services according to schedules specified in timer jobs. Many features in MOSS/Windows SharePoint Services 3.0 rely on timer jobs to run services according to a schedule.

Lets break down entire process into simpler steps. 
Step 1. Timer Job Development
Step 2. Timer Job Deployement Methodology
Step 3. Enable Timer Job

Step 1. Timer Job Development
The first thing you need to do is create a class that inherits from the Microsoft.SharePoint.Administration.SPJobDefinition class.

Let's look into WSS object model.  [Click on the image to enlarge]


To implement this class, one needs to create a few constructors and override the Execute() method. 

[code]
namespace sandeep {
 public class MyJob: SPJobDefinition{

public MyJob(): base(){
}

public MyJob(string jobName, SPService service, SPServer server, SPJobLockType targetType)
: base (jobName, service, server, targetType) {
}

public MyJob(string jobName, SPWebApplication webApplication)
: base (jobName, webApplication, null, SPJobLockType.ContentDatabase) {
this.Title = "My SharePoint Task Job";
}

public override void Execute () {
// your business logic goes here
}
}
}
[/code]

Step 2. Timer Job Deployement Methodology
MSDN suggests, that the best way to deploy a timer job is to wrap it as a feature. On feature activated and deactivating events we can write code to add/delete timer job in context of current web/site.

Take a look at the code below:-
[code]
namespace sandeep {
class FeatureToEnableJob: SPFeatureReceiver {
const string TASK_LOGGER_JOB_NAME = "My Custom Job Name";

public override void FeatureInstalled (SPFeatureReceiverProperties properties) {
}
 
public override void FeatureUninstalling (SPFeatureReceiverProperties properties) {
}

public override void FeatureActivated (SPFeatureReceiverProperties properties) {
SPSite site = properties.Feature.Parent as SPSite;

// make sure the job isn't already registered
foreach (SPJobDefinition job in site.WebApplication.JobDefinitions) {
if (job.Name == TASK_LOGGER_JOB_NAME)
job.Delete();
}

// install the job
MyJob job = new MyJob(TASK_LOGGER_JOB_NAME, site.WebApplication);

SPMinuteSchedule schedule = new SPMinuteSchedule();
schedule.BeginSecond = 0;
schedule.EndSecond = 120;
schedule.Interval = 5;
job.Schedule = schedule;

job.Update();
}

public override void FeatureDeactivating (SPFeatureReceiverProperties properties) {
SPSite site = properties.Feature.Parent as SPSite;

// delete the job
foreach (SPJobDefinition job in site.WebApplication.JobDefinitions) {
if (job.Name == TASK_LOGGER_JOB_NAME)
job.Delete();
}
}
}
}
[/code]

Step 3. Enable Timer Job
Once we have timer job wrapped as feature, either one can go for manual feature deployement process or go the WSP way (better approach)

Manual Way:
  • Deploy the strongly named assembly to the GAC.
  • Reset IIS (required for SharePoint to "see" the new timer job in the GAC).
  • Specify the receiver class and assembly in feature.xml that contains the event receivers.
  • Install the feature using stsadm.
  • Activate the feature using stsadm or settings.aspx.
WSP Way:
Please refer to my past post for this. 

cheers,

5 comments:

Unknown said...

We currently have 1 APP servers and 2 WFE in our Farm. I have written a custom timer that queries a list for notification dates. Unfortunately, when I deploy the timer job, it deploys to all servers which means that it runs on all three servers. Do you know of a way to restrict the timer job to run on only one server in the farm?

Sandeep said...

I believe one way to restrict is the OLD fashion way. Make necessary changes in your code. Put a check in your code which verify Server Name by fetching value from SPContext or any other source.

özge said...

can you please post the feature.xml?
thanks

Anonymous said...

Set the SPJobLockType attribute in the to None. It will be present in the timerjob contructor. It will run the timerjob in only one farm.

SharePointTaskMaster said...

Simle way to make a Timer Job Feature for SharePoint 2010 / Cách tạo một tính năng chạy theo lịch trình cho SharePoint 2010 http://sharepointtaskmaster.blogspot.com/2011/05/simle-way-to-make-timer-job-feature-for.html