What is a Timer Job?
A Timer Job is a periodically executed task inside SharePoint Server. It provides us a task execution environment. For example, we can execute tasks like: sending emails every hour, data updating every day, creating reports every week, etc.
From the above Figure: The Timer job will call execute method, inside of the execute method our main code snippet will create a task item in sharepoint task list.
Default Timer Jobs inside SharePoint:
There are many timer jobs inside SharePoint which do internal tasks like:
- Send emails
- Validate sites
- Delete unused sites
- Health analysis
- Product versioning
- Diagnostics
These tasks will having execution periods like:
- Minute
- Hour
- Day
- Week
- Month
Components of Connectable web parts :
- Derive CustomTimerJob Class from SPJobDefinition
- Add the three Constructors of the derived class : When ever we create the object of CustomTimerJob class, corresponding constructor will execute.
- Override the Execute method: When ever the timer job start running then the code inside the Execute method will run.
- We need to create a Feature and Feature Receiver so on activation of this feature we are going the add our timer job to SharePoint farm.
Where is my Sharepoint 2010 Custom Timer Job running?
When building a custom timer job for Sharepoint 2010, special attention should be put on where do we need this job to run. When we have a farm environment, we can choose to run the job on all servers, in one particular server, only the front end servers, etc. Depending on our requirements the timer job implementation and installation approach will change, so we should decide where we want it to run at the first place.
All Sharepoint timer jobs ultimately inherit from the SPJobDefinition class. This class provides 3 constructors:
SPJobDefinition() Default constructor needed for serialization purposes.
SPJobDefinition(String, SPService, SPServer, SPJobLockType) Instantiates a timer job associated with the given SPService.
SPJobDefinition(String, SPWebApplication, SPServer, SPJobLockType) Instantiates a timer job associated with the given SPWebApplication.
The first constructor is required for serialization and is for internal use only. One of the other two constructors will be invoked from our custom timer job constructor. The parameters passed to it will define where the timer job will run.
Here is a sample code of a custom timer job definition:
[Guid("{62FF3B87-654E-41B8-B997-A1EA6720B127}")]
class MyTimerJob1 : SPJobDefinition
{
public MyTimerJob1()
: base()
{ }
public MyTimerJob1(string name, SPService service, SPServer server,
SPJobLockType lockType) : base(name, service, server, lockType)
{ }
public MyTimerJob1(string name, SPWebApplication webApplication, SPServer server,
SPJobLockType lockType) : base(name, webApplication, server, lockType)
{ }
public override void Execute(Guid targetInstanceId)
{
//Execute Timer Job Tasks
}
}
Besides the required default constructor, we need to provide at least one of the other 2 constructors. Depending on which constructor we use, the timer job definition can be associated either with a service or a web application. It can also be associated with a particular server in the farm and a lock type. So, the first thing is that for a particular server to be eligible to run the job, it must be provisioned with the service or web app associated with the job. Then, if a particular server is passed to the constructor, the job will run only on that server (if it has the associated service or web app, otherwise the job won’t run at all). If no server is associated, then it will run on one or many servers depending on the lock type.
The SPJobLockType enumeration can take one of the following values:
None: Provides no locks. The timer job runs on every machine in the farm on which the parent service is provisioned, unless the job I associated with a specified server in which case it runs on only that server (and only if the parent service is provisioned on the server).
ContentDatabase: Locks the content database. A timer job runs one time for each content database associated with the Web application.
Job: Locks the timer job so that it runs only on one machine in the farm.
So, if we instantiate a timer job passing null as the associated server and None as the lock type, we will expect it to run on every machine in the farm on which the parent service is provisioned. If we passed an SPService to the constructor, we now which service we are talking about, and now on which servers it is provisioned. But, if we passed an SPWebApplication to the constructor, in which servers will the job run? The answer is on every web font-end server, that is the servers where the Web Application service is running on.
Remember that the different server roles that we can found on a Sharepoint farm are:
Database Server: the server that hosts the Microsoft SQL Server database for the farm. Since Sharepoint Foundation is not typically installed in this server, no jobs will run here.
Web Front End Server: server where the Microsoft SharePoint Foundation Web Application service is running on.
Application Server: Any other Sharepoint server.
Here are a couple of examples on where the jobs will run depending on the parameters passed to the constructor:
//Job associated with a web app, no server in particular and none lock:
// will run on all fron end servers.
var jobRunningOnAllFrontEndServers = new MyTimerJob1("mytimerjob",
SPWebApplication.Lookup(webAppURI), null, SPJobLockType.None);
//Job associated with a web app, one front end server and job lock:
// will run only in the frontEndServer1 server.
var jobRunningOnAParticularFronEndServer = new MyTimerJob1("mytimerjob",
SPWebApplication.Lookup(webAppURI), fronEndServer1, SPJobLockType.Job);
//Job associated with a webApp, and an app server and lock type job:
// it won't run on any server since the server specified is NOT running
// the Web Application Service
var jobRunningOnNoServer = new MyTimerJob1("mytimerjob",
SPWebApplication.Lookup(webAppURI), appServer1, SPJobLockType.Job);
//Job associated with the timer service, a particular app server and none lock:
// will run on the appServer1 server only.
var jobRunningOnAppServer = new MyTimerJob1("mytimerjob",
SPFarm.Local.TimerService, appServer1, SPJobLockType.None);
Using Subclases
There are some other classes on the Sharepoint Object Model that inherit from the SPServiceJob definition and can be used to inherit our custom timer jobs from. For example:
SPContentDatabaseJobDefinition: This job is executed by all WFE servers in the farm. Each content database is processed by only one job so that work is distributed across all the running jobs.
SPFirstAvailableServiceJobDefinition:
An abstract base class for a timer job that will be run on the first available server where the specified service is provisioned.
SPServerJobDefinition:This job definition is executed on a specific server within the SharePoint farm.
SPServiceJobDefinition: A timer job that runs on every server in the farm where the service is provisioned.
So, for example, if you need a job to run on all servers (including the app servers) it would be better to derive directly from the SPServiceJobDefinition class and, if you need a job to run in one particular app server, to derive from SPServerJobDefinition.
Differences between Timer Job and Windows Task schedulers
Timer Jobs
- Timer jobs require downtime to deploy.
- Control via Central Admin.
- Schedule of Timer Job will be backed up and restore in your normal process of SharePoint backup and restore.
- Can be deployed using standard WSP solution.
- Custom Timer Jobs provides the power to specify Job LockTypes (i.e. SPJobLockTypes) which guarantees that multiple instances of same job will never execute at the same point in time.
Windows Task Scheduler
- Windows Scheduled task doesn't require downtime to install/update.
- The task will only run on the server that you've installed it on.
- Administrator needs to manually manage backup and restore of Schedule Tasks
- No standard built in deployment method
- No multiple instance guarantee. Administrator needs to make sure that no two instances are running at the same time.
How to: Debug a Timer Job
Follow below steps to debug Timer Job:
- Put break point from where you want to start debug.
- From Debug menu select >> Attach to process
- Select OWSTIMER.exe and click on Attach button.
- Deploy project and wait until execution stops at break point.
SharePoint Timer Job vs Windows Task Scheduler (Better Timer Jobs)
Scenario:
Pros and Cons:
Considering a FARM scenario...
Single point of failure : Windows Task Scheduler need to be configured on all the web servers. If you
This is another common question which confuses lot of developers as which option is better. Traditionally
theyhave been writing console application and running them using Windows Task Scheduler, then why do
we need SharePoint Timer Jobs.
Pros and Cons:
Considering a FARM scenario...
Single point of failure : Windows Task Scheduler need to be configured on all the web servers. If you
configure to run the job on 1 server only, and this server crashes, job will not work at all.
Interface : Windows Task Scheduler have much easier interface for scheduling option. SharePoint doesn't
Interface : Windows Task Scheduler have much easier interface for scheduling option. SharePoint doesn't
have a UI to configure the jobs. There is a codeplex project though to bridge the gap. Still its hard to
configure a job to run every X number of hours in share point, where-as it's easier with Windows Task
Scheduler using multiple schedule options.
Status Reporting : Windows Task Scheduler doesn't have any reporting on when was the last time job
Status Reporting : Windows Task Scheduler doesn't have any reporting on when was the last time job
got executed and what was the status. Only option is logging. Whereas SharePoint have a UI to show
status of all the jobs and their status.
Security : In case of Windows Task Scheduler, you will need go to IT Admins and request for a special username/password to run such jobs where as SharePoint Timer Jobs automatically run under SharePoint
Security : In case of Windows Task Scheduler, you will need go to IT Admins and request for a special username/password to run such jobs where as SharePoint Timer Jobs automatically run under SharePoint
Timer Job account.
Deployment : There is no easy way to deploy Windows Task Scheduler tasks and application which need
Deployment : There is no easy way to deploy Windows Task Scheduler tasks and application which need
to executed in a FARM environment. This will require lot of manual steps by IT Admin. SharePoint jobs
can be deployed using WSP's.
OR
Steps
To debug a timer job in Visual Studio 2010
- On the Start menu, point to Administrative Tools, and then click Services.
- In the Services window, make sure the SharePoint 2010 Timer service is started.
- Open the Visual Studio 2010 project that contains your timer job.
Note: Make sure that the code has not changed since you deployed the timer job; otherwise, the debugger will not match your source code to the deployed assembly. - Set a breakpoint in the Execute method of your job definition class.
- On the Debug menu, click Attach to Process.
- In the Attach to Process dialog box, click OWSTIMER.EXE, and then click Attach.
- If the Attach Security Warning dialog box is displayed, click Attach.
- In the SharePoint Central Administration Web site, click Monitoring, and then click Review job definitions.
- Click the name of your job, and then click Run Now on the Edit Timer Job page.
- Verify that the Visual Studio 2010 debugger stops execution on your breakpoint.
OR
In order to debug a timer job or a code section within a workflow that occurs after a delay you need to attach the visual studio debugger to the OWSTIMER.exe process.
This can be done using the following steps:
STEP 1
Click On Debug then Attach To Process
STEP 2
Within the Attach to Process window ensure the Show process from all userscheckbox is selected. Find The OWSTIMER.exe process within the available processes then click Attach.
After these steps you should now be able to debug your timer job code.
SharePoint Timer Job – SPJobLockType
There are 3 SPJobLockType available:
1. SPJobLockType.None -- if you set it none, the instance will run in all the available servers in the Farm (e.g. Application Server Timer Job)
2. SPJobLockType.ContentDatabase – this will cause 3 instances to be running in each of the Web-Frontends.
3. SPJobLockType.Job – this will cause only one instance of the job to run on any of the front-end servers. (Note: it is possible to see multiple instances listed in the Job Status .. but if you look at the time it was last run.. only one would have run lately)
If you have to develop a job, you have to first decide on the type of lock you need for your job.
E.g. If your job does something with the files in the Web-Frontend server you might want to use a ContentDatabase lock.. or if you have something that manipulates the data in a list.. you will have to use Job lock.
Note: If you use other types of locks to manipulate the data in a list.. the multiple job instances will run simultaneously and cause Data Update conflict errors.
Note: If for any reason you re-deploy your job.. either put the dll directly in GAC or deploysolution.. make sure you restart the 'Windows Sharepoint Services Timer' service. (OWSTIMER.EXE)Note: The account used by the Timer service should have access to the Content Database.
Here are some sample code(s) of a custom timer job definition:
[Guid("{62FF3B87-654E-41B8-B997-A1EA6720B127}")]
class MyTimerJob1 : SPJobDefinition
{
public MyTimerJob1()
: base()
{ }
public MyTimerJob1(string name, SPService service, SPServer server,
SPJobLockType lockType) : base(name, service, server, lockType)
{ }
public MyTimerJob1(string name, SPWebApplication webApplication,SPServer server,
SPJobLockType lockType) : base(name, webApplication, server, lockType)
{ }
public override void Execute(Guid targetInstanceId)
{
//Execute Timer Job Tasks
}
}
Remember that the different server roles that we can find on a Sharepoint farm are:
- Database Server: the server that hosts the Microsoft SQL Server database for the farm. Since Sharepoint Foundation is not typically installed in this server, no jobs will run here.
- Web Front End Server: server where the Microsoft SharePoint Foundation Web Application service is running on.
- Application Server: Any other Sharepoint server.
Here are a couple of examples on where the jobs will run depending on the parameters passed to the constructor:
//Job associated with a web app, no server in particular and none lock: // will run on all fron end servers. var jobRunningOnAllFrontEndServers = new MyTimerJob1("mytimerjob", SPWebApplication.Lookup(webAppURI), null, SPJobLockType.None); //Job associated with a web app, one front end server and job lock: // will run only in the frontEndServer1 server. var jobRunningOnAParticularFronEndServer = new MyTimerJob1("mytimerjob", SPWebApplication.Lookup(webAppURI), fronEndServer1, SPJobLockType.Job); //Job associated with a webApp, and an app server and lock type job: // it won't run on any server since the server specified is NOT running // the Web Application Service var jobRunningOnNoServer = new MyTimerJob1("mytimerjob", SPWebApplication.Lookup(webAppURI), appServer1, SPJobLockType.Job); //Job associated with the timer service, a particular app server and none lock: // will run on the appServer1 server only. var jobRunningOnAppServer = new MyTimerJob1("mytimerjob", SPFarm.Local.TimerService, appServer1, SPJobLockType.None);
Restarting timer jobs using powershell in sharepoint 2010
This is the single line of powershell script which restarts the timerservice jobs in sharepoint 2010
Get -SPTimerjob | where {$_.name -match "hourly"} | start -sptimerjob.
this line says to get all the sptimerjobs where name mathces hourly and run that job.
still stsadm command works but powershell is rocking :) admin people must learn this powershell.
Get -SPTimerjob | where {$_.name -match "hourly"} | start -sptimerjob.
this line says to get all the sptimerjobs where name mathces hourly and run that job.
still stsadm command works but powershell is rocking :) admin people must learn this powershell.
Timer Jobs
Timer jobs enable you to define specific jobs to run, and when to run them
(such as search crawl log cleanup or audit log trimming jobs).
Not attach to w3wp process because this doesn’t run under web, attach to OSWTIMER.exe
They are used to fire off tasks on a schedule basis and are critical to the smooth operation of a farm
Ordinary SharePoint 2007 application we had 39 Timer’s Job, then we have 60 Jobs for SharePoint 2010 (21 new)
So, those 21 new timer jobs are:
- Application Addresses Refresh Job
- Audit Log Trimming
- Delete Job History
- Document ID enable/disable job
- Document ID assignment job
- Enterprise Server Search Master Job
- Health Analysis Job
- InfoPath Forms Services Maintenance
- Password Management
- Prepare query suggestions
- Product Version Job
- Query Logging
- Secure Store Service Timer
- Solution Daily Resource Usage Update
- State Service Delete Expired Sessions
- Timer Service Recycle
- Web Analytics Trigger Workflows Timer Job
- Windows SharePoint Services Usage Data Import
- Windows SharePoint Services Usage Data Processing
- Word Conversion Timer Job
21. Workflow
Timer job is a persistable object deriving from the SPJobDefinition class
Timer jobs used to perform background execution at regular or specific times or when you need to execute code on all or selected servers in the farm
SPJobDefinition changes---
The class now inherits from IBackupRestore which is an interface that tells that the timer job can be backed up. This interface has methods that override and implement to perform actions before and after restores and backups of timer job.
Timer jobs now have a Progress value (ranging from 0 to 100) which you can set by calling the UpdateProgress(int) method
New timer job method RunNow() creates a one-time-schedule and schedules it immediately.
There are lot of new timer job classes that all inherits from the SPJobDefinition, Some of
Pausable Timer Jobs—
done by inheriting from the SPPausableJobDefinition and overriding Execute(SPJobState) instead of Execute(Guid). use the current job state (SPJobState) to store values which are retrieved when the job is resumed.
Running jobs on all content databases---
made to perform actions on content databases. job derivative type is the SPContentDatabaseJobDefinition. Override theExecute(SPContentDatabase, SPJobState) to add your own processing. The job supports pausing.
Running jobs on all Site Collections---
new timer job type is the SPAllSitesJobDefinition. derived from the SPContentDatabaseJobDefinition and has a method called ProcessSite(SPSite, SPJobState) which you override to process the SPSite object
Running job on a specific server—
SPServerJobDefinition is a pausable timer job that is designed to be targeted to a specific server (SPServer)
Running jobs for specific services---
SPServiceJobDefinition is another pausable timer job where a specific SPService has been provisioned. similar job is theSPFirstAvailableServiceJobDefinition
Whenever list gets added to the site, site administrator should get email saying that this list is being added by so and so person at this time.
You supposed to write a job which starts the workflow every night for an approval process of some data calculations.
Create a custom timer job and specify when to run and what to do when it runs
Few classes for scheduling, we have SPWeeklySchedule, SPDailySchedule, SPMonthlySchedule, SPYearlySchedule, SPHourlySchedule, SPMinuteSchedule.
If you want to run your job every hour, you have SPHourlySchedule; like this.
different classes have different properties to be set
First thing, create a Feature class.
namespace xyz
{
public class ListAddedFeature : SPFeatureReceiver
{
const string LIST_ADDED_JOB_NAME = "ListJobNameAddingCheck";
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 == LIST_ADDED_JOB_NAME)
job.Delete();
}
// install the job
ListAddingLatestJob taskLoggerJob =new ListAddingLatestJob(LIST_ADDED_JOB_NAME, site.WebApplication);
SPMinuteSchedule schedule = new SPMinuteSchedule();
schedule.BeginSecond = 0;
schedule.EndSecond = 59;
schedule.Interval = 5;
taskLoggerJob.Schedule = schedule;
taskLoggerJob.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 == LIST_ADDED_JOB_NAME)
job.Delete();
}
}
}
}
{
public class ListAddedFeature : SPFeatureReceiver
{
const string LIST_ADDED_JOB_NAME = "ListJobNameAddingCheck";
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 == LIST_ADDED_JOB_NAME)
job.Delete();
}
// install the job
ListAddingLatestJob taskLoggerJob =new ListAddingLatestJob(LIST_ADDED_JOB_NAME, site.WebApplication);
SPMinuteSchedule schedule = new SPMinuteSchedule();
schedule.BeginSecond = 0;
schedule.EndSecond = 59;
schedule.Interval = 5;
taskLoggerJob.Schedule = schedule;
taskLoggerJob.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 == LIST_ADDED_JOB_NAME)
job.Delete();
}
}
}
}
When feature activated at that time job will be scheduled, if exists
Here is actual job definition class.
namespace xyz
{
public class ListAddingLatestJob : SPJobDefinition
{
public ListAddingLatestJob()
: base(){
}
public ListAddingLatestJob (string jobName, SPService service, SPServer server, SPJobLockType targetType)
: base (jobName, service, server, targetType) {
}
public ListAddingLatestJob(string jobName, SPWebApplication webApplication)
: base (jobName, webApplication, null, SPJobLockType.ContentDatabase) {
this.Title = "ListAdding Check";
}
public override void Execute (Guid contentDbId) {
// get a reference to the current site collection's content database
SPWebApplication webApplication = this.Parent as SPWebApplication;
SPContentDatabase contentDb = webApplication.ContentDatabases[contentDbId];
SPWeb objWeb = contentDb.Sites[0].RootWeb;
DateTime objTISiteCreationtime = objWeb.Created;
SPList taskList = contentDb.Sites[0].RootWeb.Lists["Tasks"];
SPQuery objQuery = new SPQuery();
objQuery.Query = "<Where><Gt><FieldRef Name=\"ID\"/><Value Type=\"Counter\">0</Value></Gt></Where>";
SPListItemCollection objCollection = taskList.GetItems(objQuery);
DataTable dtAllLists = objCollection.GetDataTable();
ArrayList objArrayList = new ArrayList();
if (dtAllLists != null)
{
if (dtAllLists.Rows.Count > 0)
{
for (int iCnt = 0; iCnt <= dtAllLists.Rows.Count - 1; iCnt++)
{
objArrayList.Add(Convert.ToString(dtAllLists.Rows[iCnt]["Title"]));
}
}
}
for (int iCnt = 0; iCnt <= objWeb.Lists.Count - 1; iCnt++)
{
if (!objArrayList.Contains(objWeb.Lists[iCnt].Title))
{
if (objWeb.Lists[iCnt].Created.ToShortDateString()
!= objTISiteCreationtime.ToShortDateString())
{
SPListItem newTask = taskList.Items.Add();
newTask["Title"] = objWeb.Lists[iCnt].Title;
newTask.Update();
//Write a logic to send a mail to admin
}}}}}}
{
public class ListAddingLatestJob : SPJobDefinition
{
public ListAddingLatestJob()
: base(){
}
public ListAddingLatestJob (string jobName, SPService service, SPServer server, SPJobLockType targetType)
: base (jobName, service, server, targetType) {
}
public ListAddingLatestJob(string jobName, SPWebApplication webApplication)
: base (jobName, webApplication, null, SPJobLockType.ContentDatabase) {
this.Title = "ListAdding Check";
}
public override void Execute (Guid contentDbId) {
// get a reference to the current site collection's content database
SPWebApplication webApplication = this.Parent as SPWebApplication;
SPContentDatabase contentDb = webApplication.ContentDatabases[contentDbId];
SPWeb objWeb = contentDb.Sites[0].RootWeb;
DateTime objTISiteCreationtime = objWeb.Created;
SPList taskList = contentDb.Sites[0].RootWeb.Lists["Tasks"];
SPQuery objQuery = new SPQuery();
objQuery.Query = "<Where><Gt><FieldRef Name=\"ID\"/><Value Type=\"Counter\">0</Value></Gt></Where>";
SPListItemCollection objCollection = taskList.GetItems(objQuery);
DataTable dtAllLists = objCollection.GetDataTable();
ArrayList objArrayList = new ArrayList();
if (dtAllLists != null)
{
if (dtAllLists.Rows.Count > 0)
{
for (int iCnt = 0; iCnt <= dtAllLists.Rows.Count - 1; iCnt++)
{
objArrayList.Add(Convert.ToString(dtAllLists.Rows[iCnt]["Title"]));
}
}
}
for (int iCnt = 0; iCnt <= objWeb.Lists.Count - 1; iCnt++)
{
if (!objArrayList.Contains(objWeb.Lists[iCnt].Title))
{
if (objWeb.Lists[iCnt].Created.ToShortDateString()
!= objTISiteCreationtime.ToShortDateString())
{
SPListItem newTask = taskList.Items.Add();
newTask["Title"] = objWeb.Lists[iCnt].Title;
newTask.Update();
//Write a logic to send a mail to admin
}}}}}}
IMP : How to debug the timer job definitions
use the stsadm –o execadmsvcjobs but the problem with this is it will execute all the administrative timer jobs without waiting for any job to run in schedule because it doesn’t take any parameter.
So solution is again code. Here is that one liner code that does stuff for us.
foreach (SPJobDefinition job in site.WebApplication.JobDefinitions) {
if (job.Name == LIST_ADDED_JOB_NAME)
job.Execute(site.WebApplication.ContentDatabases[0]);
}
if (job.Name == LIST_ADDED_JOB_NAME)
job.Execute(site.WebApplication.ContentDatabases[0]);
}
Adding a configuration file to fetch values from Timer Job. ( two ways)
1.To get reference of the associated web.config file
Get the reference of the SPWeb or SPSite (depending upon feature scope) during feature activation through
SPWeb objWeb = properties.Feature.Parent as SPWeb.
InvoiceLogger objInvoiceLoggerJob = new InvoiceLogger(CONSTANTS.JOB_NAME, objWeb);
2. Add a new constructor on your job definition feature
public InvoiceLogger(string strJobName, SPWebApplication objWebAppToAssociate)
: base(strJobName, objWebAppToAssociate, null, SPJobLockType.ContentDatabase)
{
this.Title = strJobName;
this._spweburlPersisted = strJobName;
}
and there should be one variable holding persisted information
[Persisted]
public string _spweburlPersisted;
Now in the execute method, get the reference of the web url through persisted string information, content database.
public void Execute(Guid _contentDBID)
{
///Get the reference to contentDB
SPWebApplication objWebApp = this.Parent as SPWebApplication;
SPContentDatabase objContentDb = objWebApp .ContentDatabases[contentDbId];
using (SPSite objSite = new SPSite(objContentDb .Sites[0].RootWeb.Url))
{
using (SPWeb objWeb= objSite .OpenWeb())
{
Configuration webconfig = WebConfigurationManager.OpenWebConfiguration("/", objWebApp.Name);
string value = webconfig.AppSettings.Settings["eUserName"].value;
string constringVal = WebConfigurationManager.OpenWebConfiguration("/",objWebApp.Name).ConnectionStrings["constring"].Value;
}
}
SPWeb objWeb = properties.Feature.Parent as SPWeb.
InvoiceLogger objInvoiceLoggerJob = new InvoiceLogger(CONSTANTS.JOB_NAME, objWeb);
2. Add a new constructor on your job definition feature
public InvoiceLogger(string strJobName, SPWebApplication objWebAppToAssociate)
: base(strJobName, objWebAppToAssociate, null, SPJobLockType.ContentDatabase)
{
this.Title = strJobName;
this._spweburlPersisted = strJobName;
}
and there should be one variable holding persisted information
[Persisted]
public string _spweburlPersisted;
Now in the execute method, get the reference of the web url through persisted string information, content database.
public void Execute(Guid _contentDBID)
{
///Get the reference to contentDB
SPWebApplication objWebApp = this.Parent as SPWebApplication;
SPContentDatabase objContentDb = objWebApp .ContentDatabases[contentDbId];
using (SPSite objSite = new SPSite(objContentDb .Sites[0].RootWeb.Url))
{
using (SPWeb objWeb= objSite .OpenWeb())
{
Configuration webconfig = WebConfigurationManager.OpenWebConfiguration("/", objWebApp.Name);
string value = webconfig.AppSettings.Settings["eUserName"].value;
string constringVal = WebConfigurationManager.OpenWebConfiguration("/",objWebApp.Name).ConnectionStrings["constring"].Value;
}
}
2.To get values from app.config
In the class library of Timer Jobs, add a new OWSTIMER.exe.config file and add configuration Keys like ..connectionstring or ..appsetting in it.
Deploy the feature using stsadm commond.
Place the OWSTIMER.exe.config file in
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN
or add the configuration tags into existing OWSTIMER.exe.config file
Deploy the feature using stsadm commond.
Place the OWSTIMER.exe.config file in
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN
or add the configuration tags into existing OWSTIMER.exe.config file
The Timer Job item also provides a custom logging class named Logger. This class provides a LogInfo and LogError clas that you can use to trace the progress of the timer job. You can easily add additional methods for more control over the logging
**************************************************************
when you need to perform background execution at regular or specific times or when you need to execute code on all or selected servers in the farm
The different Variation Timer Jobs
Variations Create Hierarchies Job Definition--- (By default, this timer job runs once a day)
Class: Microsoft.SharePoint.Publishing.Internal.CreateVariationHierarchiesJobDefinition
Variations Create Page Job Definition---
Communication between worker process and Timer Jobs
WSS provides a built in mechanism for this by providing the SPWorkItemJobDefinition class. Timer job definitions derived from this class are able to read configuration data from work items, which are stored in the ScheduledWorkItems table in the content database. The Sharepoint object model allows adding, reading and removing work items to/from this table.
As many different timer jobs can work on the same ScheduledWorkItems table it is necessary to ensure that eachScheduledWorkItems carries a type information (a unique id) to ensure that the timer job picks up the correct work items
When the appropriate timer job runs the next time, it reads all work items related to this timer job from the ScheduledWorkItemstable and processes them one by one. After the timer job has completed the processing of a work item, it removes the work item from the ScheduledWorkItems table
Underlying WSS Timer Job framework
SPJobDefinition--- All timer job are persistable objects derived from the SPJobDefinition class
SPPausableJobDefinition--- new abstract class derived from SPJobDefinition has been included which supports pausing and restart of timer jobs: SPPausableJobDefinition . Execute method, which allows to hand-in a job state to the timer job, derived from SPPausableJobDefinition can use this job state (SPJobState) to store values when the job is paused
SPWorkItemJobDefinition---2007 introduced a SPWorkItemJobDefinition Timer job class derived from SPJobDefinition which process a list of work items of a specific type, 2010, SPWorkItemJobDefinition now also supports the pause and resume functionality and is now derived from SPPausableJobDefinition.
In SharePoint 2010 the actual Timer job derived from SPWorkItemJobDefinition, implement two methods
WorkItemType() which returns the unique ID of the work item type that should be processed in the timer job, andProcessWorkItem() which processes one single work item of the defined type.
SPWorkItemJobDefinition base class handles the rest of the processing like reading the work items from the database, updating the Timer job progress), pausing and resume.
Variation Timer Jobs Framework--- All variation timer jobs implement the SPWorkItemDefinition class.VariationsSpawnJobDefinitionBase has been implemented which acts as base class to four of the five variation timer jobs
Introduction to Windows SharePoint Services Timer Jobs
inherits from the Microsoft.SharePoint.Administration.SPJobDefinition class
deploy the assembly that contains this class to the global assembly cache (GAC)
Then you must deploy, or install, the timer job into the server farm.
The purpose of the custom timer job is to act as a replacement for the Windows SharePoint Services warmup scripts
Creating Custom Timer Jobs
There are three different types of locking, as defined by the SPJobLockType enumeration:
- SPJobLockType.ContentDatabase Locks the content database. A timer job runs one time for each content database that is associated with the Web application.
- SPJobLockType.Job Locks the timer job so that it runs on only one machine in the farm.
- SPJobLockType.None No locks. The timer job runs on every machine on which the parent service is provisioned.
you do not have to run the same job simultaneously on the same server, so the constructor can set the locking type on the job itself
|
Practically Create Custom Timer Jobs In SharePoint :-
1-Custom Timer Job in SharePoint 20102-Create custom Timer jobs in sharepoint 2010-- For Sending Email
3-Step by Step procedures to create a Timer Job in SharePoint 2013
4-A Timer Job is a periodically executed task inside SharePoint Server like sending emails or deleting
5-Creating Custom Timer Jobs programatically in SharePoint 2010
6-Timer Jobs in SharePoint 2010
Dear Singh
ReplyDeleteis your explanation possible apply to Nintex workflow .Issue: Resolving Stuck Workflow Timer Jobs ? Frantisek