很多应用程序都需要在指定的时间(每年,每月,每周,每天,每小时)自动在后台重复执行某个流程,一般为批量处理一些记录,执行比较长的操作等.在SharePoint2013/2010中,Timer Jobs负责host这些重复执行的流程,以及他们的排程(Schedule),本文将以SharePoint2013为例介绍如何使用TimerJobs,但是90%的步骤和概念是和SharePoint2010中一致的。
可以在管理中心查看Timer Jobs(系统自带有很多Timer Jobs):
SharePoint Timer Service 负责执行了调度所有的 TimerJob,因此你需要确保运行该服务的账号有访问TimerJob里面需要用到的资源的权限。
下面介绍如何在SharePoint 2013:
1. 创建一个Empty的SharePoint solution(Farm) ,并建立如下代码结构
MyTimerJob.cs 负责定义 SPJobDefinition:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.SharePoint; using Microsoft.SharePoint.Administration; namespace TestTimerJob { // 首先是要自定义一个类,继承自 SPJobDefinition public class MyTimerJob : SPJobDefinition { // 该构造只用于序列化和反列化,因为timer job的Definition 初始化后成为instance需要保存在数据库中 public MyTimerJob() : base() { } // 创建针对SPService application的timer job 是调用的构造 public MyTimerJob(string jobName, SPService service, SPServer server, SPJobLockType lockType) : base(jobName, service, server, lockType) { this.Title = "Products Timer Job"; } // 创建针对web application的timer job 是调用的构造 public MyTimerJob(string jobName, SPWebApplication webapp) : base(jobName, webapp, null, SPJobLockType.ContentDatabase) { this.Title = "Products Timer Job"; } // 每次执行到Timer Job时要执行的方法。跟据Timer Job 的Schedule public override void Execute(Guid targetInstanceId) { SPWebApplication webapp = this.Parent as SPWebApplication; SPContentDatabase contentDb = webapp.ContentDatabases[targetInstanceId]; // 取参数,通过Properties可以从外部传递参数,但要求参数可以被序列化和反列化 string siteUrl = this.Properties["SiteUrl"].ToString(); using (SPSite site = new SPSite(siteUrl)) { // 这里可写自己的逻辑 } // 这里可写自己的逻辑 } } }
MyTimerJob Feature.EventReceiver.cs 负责实例化SPJobDefinition,设置排程(schedule),传递参数:
using System; using System.Runtime.InteropServices; using System.Security.Permissions; using Microsoft.SharePoint; using Microsoft.SharePoint.Administration; namespace TestTimerJob.Features.MyTimerJob_Feature{ [Guid("d3209596-8612-4891-bf08-dc0fa0f0cb98")] public class MyTimerJob_FeatureEventReceiver : SPFeatureReceiver { const string JobName = "My Timer Job"; public override void FeatureActivated(SPFeatureReceiverProperties properties) { // 注意此处as 后面是SPSite还是SPWeb, SPFarm ...要根据Feature 的Scope SPSite site = properties.Feature.Parent as SPSite; DeleteJob(site); // Delete Job if already Exists CreateJob(site); // Create new Job } private static void DeleteJob(SPSite site) { foreach (SPJobDefinition job in site.WebApplication.JobDefinitions) if (job.Name == JobName) job.Delete(); } private static void CreateJob(SPSite site) { // 初始化 SPJobDefinition MyTimerJob job = new MyTimerJob(JobName, site.WebApplication); // 传递参数 job.Properties.Add("SiteUrl", site.Url); // 设置 schedule, 可选 SPDailySchedule, SPWeeklySchedule, SPYearlySchedule,SPMonthlyByDaySchedule,SPHourlySchedule,SPMinuteSchedule SPMinuteSchedule schedule = new SPMinuteSchedule(); schedule.BeginSecond = 0; schedule.EndSecond = 5; schedule.Interval = 5; job.Schedule = schedule; job.Update(); } public override void FeatureDeactivating(SPFeatureReceiverProperties properties) { // 删除 Timer Job的实例 DeleteJob(properties.Feature.Parent as SPSite); // Delete the Job } } }