很多应用程序都需要在指定的时间(每年,每月,每周,每天,每小时)自动在后台重复执行某个流程,一般为批量处理一些记录,执行比较长的操作等.在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
}
}
}