Thursday, 7 February 2013

Create a Custom Timer Job in SharePoint 2010

A Timer Job is a periodically executed task inside SharePoint Server like sending emails or deleting the list items etc... in timely manner.

DLL or Namespace reference required in the scheduled in the class

using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

Steps To create a custom timer job:
  1. Open Visual Studio 2010 and select File –> New –> Project
  2. In the New Project window, under Installed Templates, select SharePoint –> 2010 and select Empty SharePoint Project. Give the project a Name and click OK.
  3. Enter the URL for SharePoint local site, check the Deploy as a farm solution, and click Finish.
  4. Create a new class.Right click on the project in the Solution Explorer window and select Add –> New Item.
  5. In the Add New Item window, under Installed Templates, select Visual C# –> Code and select Class.  Give the class a name as "ListTimerJob" and click OK.
  6. The new class needs to inherit from the Microsoft.SharePoint.Administration.SPJobDefinition class. 
    • Add a default constructor to the class that inherits from the default constructor of the base class. This is required for the serialization and de-serialization of your timer job.
    • Add a constructor that accepts an argument of type string(jobname) and a type SPWebApplication, as shown in the following code. This enables the base SPJobDefinition class to instantiate your timer job within a specific Web application.
    • The SPJobDefinition base constructor provides alternative overloads that you can use if you want to scope your timer job to an SPService instance instead of a Web application. 
    • And finally Within the ListTimerJob class, override the Execute method. The method should accept an argument of type Guid. In this case, the GUID represents the target Web application.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Administration;

namespace SPTimerJobExample
{
    public class ListTimerJob : SPJobDefinition
    {
    }
    //Optional
    public ListTimerJob(string jobName, SPService service, SPServer server, SPJobLockType targetType): base(jobName, service, server, targetType)
     {
      // if you want to scope your timer job to an SPService instance instead of a Web                                                     application,then you can use this constructor.
     }//
    public ListTimerJob(string jobName, SPWebApplication webApplication)
            : base(jobName, webApplication, null, SPJobLockType.ContentDatabase)
    {
            this.Title = "List Timer Job";
    }
    public override void Execute(Guid contentDbId)
    {
            SPSite site = new SPSite("http://spdemo2010:2012/");
            SPWeb web = site.OpenWeb();
            SPList list = web.Lists["TeamChat"];
            SPListItemCollection listItems = list.Items;
            for (int i = listItems.Count-1; i >= 0; i--)
                {
                    listItems[i].Delete();
                }
            web.Dispose();
            site.Dispose();
    }
}

7. Add a Feature to the solution by right clicking on Features in the Solution Explorer window and                   selecting Add Feature.So now Feature 1 will be created.
8. Right click on Feature1 and select Add Event Receiver.
9. A new event receiver class is created that handles the feature’s events.Copy and paste the following code, which handles the FeatureActivated event, installing the custom timer job, and handles the FeatureDeactivating event, uninstalling the custom timer job.


namespace UpshotSP.Features.Feature1
{
   [Guid("9a724fdb-e423-4232-9626-0cffc53fb74b")]

public class Feature1EventReceiver : SPFeatureReceiver
    {
        const string List_JOB_NAME = "List Timer Job";
        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 == List_JOB_NAME )
                    job.Delete();
            }
            // install the job
            ListTimerJob listLoggerJob = new ListTimerJob(List_JOB_NAME , site.WebApplication);
            SPDailySchedule schedule = new SPDailySchedule();
            schedule.BeginHour = 2;
            schedule.BeginMinute = 10;
            schedule.BeginSecond = 0;
            schedule.EndHour = 2;
            schedule.EndMinute = 20;
            schedule.EndSecond = 0;
            listLoggerJob.Schedule = schedule;
            listLoggerJob.Update();
        }
        // method below to handle the event raised before a feature is deactivated.
        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 == List_JOB_NAME)
                    job.Delete();
            }
        }
    }
}


10. Select the appropriate scope where the new feature will be activated.  Double click Feature1.Feature in the Solution Explorer window and choose the desired Scope from the dropdown menu.
11. Deploy the solution by right clicking on the project in the Solution Explorer window and selecting Deploy.
12. Navigate to the SharePoint “TestList” list and verify that a new item has been added with the current day/time as the title and you see your custom timer job named "List Timer Job" under Manage Timer jobs in Central Admin.
Note: You can see all Timer Jobs from Central Administration > Monitoring > Manager Timer Jobs.
SPSchedule class is used to schedule the Timer Job in a timely manner,You can also use other schedule class as mentioned below,
  • Minute
  • Hour
  • Day
  • Week
  • Month
Ex:
            SPMinuteSchedule schedule = new SPMinuteSchedule();
            schedule.BeginSecond = 0;
            schedule.EndSecond = 59;
            schedule.Interval = 5;
            job.Schedule = schedule; 
            job.Update();
_____________________________________________________________________________

A better way to delete list item if you have a lot of items is to use a default query and specify a row limit of 100.
Also to delete fast and efficiently, use a delete batch command CAML script.

StringBuilder sbDelete = new StringBuilder("<Batch>");
for (int x = listItems.Count-1; x >= 0; x--)
{

 sbDelete.Append("<Method>") ;
            sbDelete.Append("<SetList Scope='Request'>" & listItems[x].ID.ToString & "</SetList>"); 
            sbDelete.Append("<SetVar Name='Cmd'>DELETE</SetVar>"); 
            sbDelete.Append("<SetVar Name='ID'>listItems[x].ID</SetVar>"); 
            sbDelete.Append("</Method>"); 
}
sbDelete.Append("</Batch>");
web.AllowUnsafeUpdates = True;
web.ProcessBatchData(sbDelete.ToString()); 

1 comment: