[SharePoint 2010] TimerJob开发

需求:根据查询文档库中将过期的文档。

实现:通过自定义TimerJob,来定时查询文档库中即将过期的文档。

资料:SharePoint 2010 TimerJob开发参考

Timer Job的组成部分:

  1. 定义:Timer Job的定义是一个继承自SPJobDefinition的类,在类中定义Timer Job的执行逻辑。
  2. 实例:定义的实例,通过实例的各种属性来控制TimerJob的执行。
  3. 执行计划:一个TimerJob可以跟一个或多个执行计划(SPSchedule)关联。

Timer Job关联:

  一个实例必须关联到一个SharePoint Web Application(SPWebApplication)或者一个SharePoint Service Application(SPService)。这取决与采用的哪个构造函数。

创建Timer Job定义

SPJobDefinition提供了三个构造函数:默认的(无参数)、与SPWebApplication关联的、与SPService关联的。

我们的定义类需要实现默认的(无参数)的构造函数,并实现其他两个中的任意一个构造函数。

public class RetrieveExpire : SPJobDefinition
    {
        public RetrieveExpire()
            : base()
        {

        }

        public RetrieveExpire(string jobName, SPService service, SPServer server, SPJobLockType targetType)
            : base(jobName, service, server, targetType)
        {

        }

        public RetrieveExpire(string jobName, SPWebApplication webApplication)
            : base(jobName, webApplication, null, SPJobLockType.ContentDatabase)
        {

            this.Title = "RetrieveExpire";
        }
    }

指定Timer Job的LockType

 
Lock Type Describtion
None

该类型表示在TimerJob指定了SPWebApplicaiton或SPService的情况下,TimerJob实例将会在服务器场的每台

服务器中执行一次。

ContentDatabase

该类型表示在TimerJob指定了SPWebApplicaiton的情况下,TimerJob将会在该SPWebApplication关联的所有

ContentDatabase中执行一次。当指定这种LockType时,方法Excute的参数targetInstanceId就是

当前正在执行TimerJob的ContentDatabase的GUID。

Job 该类型表示TimerJob仅执行一次。

重写Excute方法

        public override void Execute(Guid targetInstanceId)
        {
                //在TimerJob执行的代码逻辑
        }

定义TimerJob执行计划

SharePoint提供了SPSchedule类,该类提供了常用的计划类型。

ClassName Describtion
SPYearlySchedule 每年执行一次
SPMonthlySchedule 每月的特定日期执行:每月的15日执行
SPMonthlyByDaySchedule 每月的特定的天数和星期执行:每月的第三个星期三执行。
SPWeeklySchedule 每周执行一次
SPDailySchedule 每天执行一次
SPHourlySchedule 每小时执行一次
SPMinuteSchedule 每分钟执行一次,参数n:执行间隔。
SPOntTimeSchedule 仅执行一次

每10分钟执行一次的计划

            RetrieveExpire retrieveJob = new RetrieveExpire(TIMER_JOB_NAME, site.WebApplication);
            SPMinuteSchedule mySchedule = new SPMinuteSchedule()
            {
                BeginSecond = 0,
          EndSecond=59, Interval
= 10 }; retrieveJob.Schedule = mySchedule; retrieveJob.Update();

BeginSecond和EndSecond指定了计划的执行范围,SPSchedule通过属性NextOccurrence来确定下一次执行的时间。属性NextOccurrence返回一个在执行范围内的随机时间(DateTime),这可以避免多个服务器中的TimerJob在同一时间执行。

如果我们定义的执行范围比较小,那SharePoint会不会遗漏执行呢?

现在假定我们定义的范围是Begin(10:00:01)End(10:00:02),SharePoint会根据这两个时间点计算出一个随机时间,即TimerJob将在10:00:01或10:00:02执行,因为在给出的时间范围内,只有这两个时间点是有效的。

假设,在10:00:00的时候SharePoint timer service开始检查是否有待执行的timer job,这个时候还不会执行timer job;在10:00:05的时候SharePoint timer service第二次检查是否有待执行的timer job,这个时间点已经在timer job的执行范围内,那是否意味着timer job不会执行呢?当然不是了,SharePoint 之前就已经计算出timer job将要执行的时间(NextOccurrence),如果当前时间超过了 该执行时间,SharePoint就是开始执行该timer job,而不是跳过它。

为Timer Job定义参数

两种方式:

  • 从指定位置的文件中读取,适合仅仅一个timer job实例的情况。
  • 通过SPJobDefinition的Properties属性(存储的值必须是可序列化的)

删除Timer Job

            SPSite site = properties.Feature.Parent as SPSite;

            // delete the job
            foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
            {
                if (job.Name == TIMER_JOB_NAME)
                    job.Delete();
            }

Timer Job运行的宿主服务器

这取决于下面几个因素:

  • 初始化TimerJob实例时指定的SPLockType
  • 部署TimerJob代码的宿主服务器
  • TimerJob是否和特定的SPServer关联
  • 服务器是否配置了TimerJob关联的SPWebApplication或SPService

如果SPLockType被设置为Job或ContentDatabase,表明该TimerJob只能在一台服务器上执行。默认情况下,部署TimerJob代码的宿主服务器即是TimerJob的运行服务器,除非该服务未配置TimerJob所关联的SPWebApplication或SPService,这中情况下,TimerJob将会选择服务器场中第一个配置了TimerJob所关联的SPWebApplication或SPService的服务器上运行。

如果SPLockType被设置为None,那么TimerJob将会选择服务器场中所有配置了TimerJob所关联的SPWebApplication或SPService的服务器上运行。

如果TimerJob已经指定了关联的SPServer,那么无论SPLockType为何值,该TimerJob只会在指定的SPServer中运行。如果指定的SPServer无法执行,TimerJob将不会执行。

部署TimerJob

通过Event Feature在SharePoint中部署TimerJob

        const string TIMER_JOB_NAME = "RetrieveExpire";
        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 == TIMER_JOB_NAME)
                    job.Delete();
            }

            // install the job
            RetrieveExpire retrieveJob = new RetrieveExpire(TIMER_JOB_NAME, site.WebApplication);
            SPMinuteSchedule schedule = new SPMinuteSchedule();

            schedule.BeginSecond = 0;
            schedule.EndSecond = 59;
            schedule.Interval = 1;
            retrieveJob.Schedule = schedule;
            retrieveJob.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 == TIMER_JOB_NAME)
                    job.Delete();
            }
        }
posted @ 2012-10-16 14:14  一只小小菜鸟  阅读(530)  评论(0编辑  收藏  举报