This article deals with SharePoint Custom Timer jobs. It outlines when to create Custom Timer Jobs, how to create a Custom Timer Job, how to debug it in Visual Studio and how to deploy it.
1) If you have a task which has to be done at a scheduled time only...
Example: You have to synchronize the data between two lists which are in different site collections and they should be synchronized every hour.
2) If the task has complex business logic which will tax server performance and you want to schedule it to run at night...
Example: You have to fetch daily data from an external SQL database, perform some business logic on it and store the resulting set in a couple of SharePoint lists. Since this would tax your SharePoint Server, it should be performed during a time with low user activity, like at night.
There are two ways to implement these scenarios; either as a console application or as a SharePoint custom Timer Job. The Custom Timer Job option is better since there is no user involvement and it is easier to maintain a Timer Job. You can manage it directly from Central Administration. Timer Jobs are created at the web application level.
Create a class that Inherits from the "Microsoft.SharePoint.Administration.SPJobdefinition" class. Implement the constructors as shown in the code snippet below and implement the Execute() method for a "Windows SharePoint Services Timer" call when the job is executed.
Consider the different available job locks:
Refer to this article to get a clear picture of job locks.
Below is an example of a Custom Job creation using SPJobLock
class SyncListsJob:SPJobDefinition { public SyncListsJob ():base() { } public SyncListsJob (string jobName, SPService service, SPServerserver, SPJobLockType targetType) :base (jobName, service, server, targetType) { } public SyncListsJob (string jobName, SPWebApplication webApplication):base(jobName, webApplication, null, SPJobLockType.Job) { this.Title = "Job Name" } public override void Execute(Guid targetInstanceId) { SPWebApplication webapplication = (SPWebApplication)this.Parent; //WRITE YOUR CUSTOM CODE HERE } }
Now your Timer Job is ready and we have to install it on the farm and deploy to our web application. The "recommended way" for doing this would be to create a Feature Receiver and implement the FeatureActivated event. In this event, you can instantiate your job, set the job schedule and update the Job.
<?xml version="1.0" encoding="utf-8"?>
<Feature Id="2149d631-52cd-49cc-ab00-af9662585680" Title="Synchronize Lists Job" Description="It synchronizes the lists on two different site collections" Version="12.0.0.0" Hidden="FALSE" ActivateOnDefault="FALSE" AlwaysForceInstall="FALSE" Scope="WebApplication" DefaultResourceFile="core" ReceiverAssembly="SyncLists, Version=1.0.0.0, Culture=neutral,PublicKeyToken=a6e86a64132a89ed" ReceiverClass="SyncLists.SyncListsFeatureReceiver" xmlns="http://schemas.microsoft.com/sharepoint/">
</Feature>
Class SyncListsFeatureReceiver:SPFeatureReceiver { public override void FeatureActivated(SPFeatureReceiverProperties properties) { try { SPWebApplication webApp = (SPWebApplication)properties.Feature.Parent; //Good Practice to delete the older version of Job if it exists foreach (SPJobDefinition job in webApp.JobDefinitions) { if (job.Name.ToLower() == myJobName.ToLower()) { job.Delete(); } } //Install the job definition SyncListsJob tempJob = new SyncListsJob (myJobName,webApp); //If you want to run it every hour, use SPHourlySchedule class to configure. //This one will run between 0 to 5 mintues of every hour SPHourlySchedule schedule = new SPHourlySchedule(); schedule.BeginMinute = 0; schedule.EndMinute = 5; tempJob.Schedule = schedule; tempJob.Update(); } catch (Exception ex) { } } public override void FeatureDeactivating(SPFeatureReceiverProperties properties) { try { SPWebApplication webApp = (SPWebApplication)properties.Feature.Parent; //delete the job foreach (SPJobDefinition job in webApp.JobDefinitions) { if (job.Name.ToLower() == myJobName.ToLower() { job.Delete(); } } } catch (Exception ex) { } } }
SPMinuteSchedule minSchedule = new SPMinuteSchedule(); minSchedule.BeginSecond = 0; minSchedule.EndSecond = 5; minSchedule.Interval = 10; tempJob.Schedule = minSchedule; tempJob.Update();
SPDailySchedule tempSchedule = new SPDailySchedule(); tempSchedule.BeginHour = 23; tempSchedule.BeginMinute=5; tempSchedule.BeginSecond = 0; tempSchedule.EndSecond = 15; tempSchedule.EndMinute = 5; tempSchedule.EndHour = 23; tempJob.Schedule = schedule; tempJob.Update();
SPMonthlySchedule schedule = new SPMonthlySchedule(); schedule.BeginDay = 1; schedule.EndDay = 1; schedule.BeginHour = 1; schedule.EndHour = 1; schedule.BeginMinute = 15; schedule.EndMinute = 30; tempJob.Schedule = schedule; tempJob.Update();
SPWeeklySchedule schedule = new SPWeeklySchedule(); schedule.BeginDayOfWeek = DayOfWeek.Monday; schedule.BeginHour = 2; schedule.BeginMinute = 1; schedule.BeginSecond = 0; schedule.EndSecond = 5; schedule.EndMinute = 1; schedule.EndHour = 2; schedule.EndDayOfWeek = DayOfWeek.Monday; tempJob.Schedule = schedule; tempJob.Update();
SPYearlySchedule JobSchedule = new SPYearlySchedule(); JobSchedule.BeginMonth = 1; JobSchedule.EndMonth = 1; JobSchedule.BeginDay = 23; JobSchedule.EndDay = 23; JobSchedule.BeginHour = 9; JobSchedule.EndHour = 9; JobSchedule.BeginMinute = 5; JobSchedule.EndMinute = 5; JobSchedule.BeginSecond = 0; JobSchedule.EndSecond = 5; tempJob.Schedule = schedule; tempJob.Update();