SharePoint: list running timer jobs (C#)
Role of the timer jobs in SharePoint
Timer jobs are a convenient way to perform background tasks in SharePoint. Writing custom jobs for our solution lets us define job schedule and report progress using a simple API. When the job definition is added to a farm (e.g. from solution code, usually on a feature activation event receiver), we can also manage the job and monitor progress of the running jobs in Central Administration (http://server-name/_admin/ServiceJobDefinitions.aspx
).
A look at the architecture
The process that is responsible for executing timer jobs is OWSTimer.exe
. Jobs can be associated with either an Web application or Service Application. If you need more information about the architecture and internals of this part of SharePoint, be sure to check the article by Veena Sarda [1].
Jobs can be managed from the dedicated pages in CA or with the use of PowerShell. While the Central Administration view allows us to see the current state of the jobs in the browser window, some of use will need to check jobs status or history in C# code.
Listing running jobs in C#
The function presented below returns names of all the timer jobs currently running in a SharePoint farm. With slight modification it might check for example whether a single particular job is running. Along with the function to determine last run date of a timer job in C# it allows to know precisely about the status of a job at a given time. The code was tested on version 2010.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
/// <summary> /// Return titles of currently running timer jobs in a SharePoint farm /// </summary> /// <returns>Collection of strings containing titles of the jobs currently running</returns> private List<string> GetRunningJobsTitles() { List<string> runningJobsTitles = new List<string>(); var services = SPFarm.Local.Services; foreach (SPService service in services) { var serviceRunningJobs = service.RunningJobs.Cast<SPRunningJob>(); foreach (SPRunningJob job in serviceRunningJobs) { runningJobsTitles.Add(job.JobDefinitionTitle); } // Unlike job definitions, running jobs that belong to a web application *are* present in // parent service's RunningJobs collection. Therefore, itarating web applications would // result in duplicates. For those who would like to try for themselves, here's the code //if (service is SPWebService) //{ // var webService = (SPWebService)service; // foreach (SPWebApplication webApp in webService.WebApplications) // { // var jbs = webApp.RunningJobs.Cast<SPRunningJob>(); // foreach (SPRunningJob job in jbs) // { // runningJobsTitles.Add(job.JobDefinitionTitle); // } // } //} } return runningJobsTitles; } |
While it’s quite easy and could be presented as a one-liner, the official documentation is lacking. So far there was much confusion on the subject in the stack exchange answers and top Google results, so I’m just posting it for reference. Most people try to use the HistoryEntries
property of a SPJobDefinition
and fail, because the entries are only written to the history when timer job terminates–either successfuly or when it’s aborted.
Sources and useful articles
Here are some references on the subject.
[…] about the currently running jobs rather than those from the past, you might also want to read SharePoint: list running timer jobs (C#). Good […]