在 SharePoint 2010 中创建面向特定服务的计时器作业

**摘要:**了解如何创建与 SharePoint 2010 中的特定 SharePoint 服务相关联的 Microsoft SharePoint 2010 计时器作业。

Wrox 徽标

Wrox SharePoint 书籍(该链接可能指向英文页面)

上次修改时间: 2015年3月9日

适用范围: Business Connectivity Services | Open XML | SharePoint Designer 2010 | SharePoint Foundation 2010 | SharePoint Online | SharePoint Server 2010 | Visual Studio

本文内容
SharePoint 2010 中的计时器作业概述
准备创建 SharePoint 计时器作业
创建 SharePoint 计时器作业
启用 SharePoint 计时器作业配置
部署计时器作业
测试和调试 SharePoint 计时器作业
结论
关于作者
其他资源

**作者:**Bryan Phillips

**编辑:**SharePoint 2010 文章的 WROX 技术编辑

目录

  • SharePoint 2010 中的计时器作业概述

  • 准备创建 SharePoint 计时器作业

  • 创建 SharePoint 计时器作业

  • 启用 SharePoint 计时器作业配置

  • 部署计时器作业

  • 测试和调试 SharePoint 计时器作业

  • 结论

  • 关于作者

  • 其他资源

SharePoint 2010 中的计时器作业概述

Microsoft SharePoint 2010 计时器作业执行维护您的 SharePoint 场所需的大部分后端作业。计时器作业是在计划的时间在一台或多台服务器上运行的可执行任务。可将计时器作业配置为正好运行一次,或按定期计划运行。计时器作业类似于 Microsoft SQL Server 代理作业,这些代理作业可通过备份数据库、整理数据库文件碎片和更新数据库统计信息来维护 SQL Server 安装。SharePoint 使用计时器作业来维护长时间运行的工作流、清理旧的网站和日志以及监控服务器场以发现问题。根据您的 SharePoint 版本和任何已安装的第三方产品,您在服务器场中可以拥有多个计时器作业,或者仅少数计时器作业。计时器作业有一些优势。它们可以定期并独立于正在访问您的 SharePoint 网站的用户运行,它们可以从您的 Web 前端服务器卸载长时间运行的进程,从而提高您页面的性能和响应能力,它们还可在比您的 SharePoint 网站和应用程序页中的代码更高的权限下运行代码。

您可使用 SharePoint 2010 管理中心中的"作业定义"页查看您服务器场中的计时器作业。若要访问"作业定义"页,请依次单击"所有程序"、"Microsoft SharePoint 2010 产品"、"SharePoint 2010 管理中心"。在"管理中心"网站上,单击"监控"链接。最后,单击"监控"页的"计时器作业"部分中的"复查作业定义"链接。将显示您的服务器场中计时器作业定义的列表,如图 1 所示。

图 1. SharePoint 计时器作业定义的列表

SharePoint 计时器作业定义的列表

由于 SharePoint 计时器作业在后台运行,因此,即使没有用户访问您的 SharePoint 网站,计时器作业也会在后台执行其任务。Windows SharePoint Services 定时服务在您的服务器场中运行计时器作业。必须启用该服务并在您服务器场中的每台服务器上运行它。该服务使各种 SharePoint 计时器作业能够配置和维护服务器场中的服务器。如果停止服务器上的 Windows SharePoint Services 定时服务,则您还将停止该服务器上运行的所有 SharePoint 计时器作业;例如,为您的 SharePoint 网站编制索引,从 Active Directory 中导入用户,并执行会影响 SharePoint 的性能和可用性的许多其他进程的作业。

准备创建 SharePoint 计时器作业

必须先在 Windows Vista、Windows 7 或 Windows Server 2008 上安装 Microsoft Visual Studio 2010(专业版、高级专业版和旗舰版),之后您才能创建您的 SharePoint 计时器作业。必须在开发计算机上安装 SharePoint 2010。

安装所需软件后,在 Visual Studio 中创建新的 SharePoint 项目,方法是选择"文件"、"新建"、"项目",这将显示"新建项目"对话框,如图 2 所示。在该对话框中,确保在对话框顶部的下拉列表中选择了".NET Framework 3.5",并展开对话框左侧窗格中的项目模板列表,直到"SharePoint"下显示"2010"。选择"2010"以在对话框的右侧窗格中显示 SharePoint 2010 项目模板的列表。从模板列表中选择"空白 SharePoint 项目",在对话框底部指定项目信息,然后单击"确定"。您可使用新项目开发您的新计时器作业,将其打包以部署到 SharePoint,然后对其进行调试。

图 2."新建项目"对话框

"新建项目"对话框

备注

您的"新建项目"对话框可能与图 2 中所示的对话框看起来不同,具体取决于您的 Visual Studio 配置。

在"新建项目"对话框中单击"确定"后,将立即显示"SharePoint 自定义向导"对话框,如图 3 所示。在文本框中键入您的 SharePoint 网站的 URL,选择"部署为场解决方案",然后单击"完成"。您必须选择"部署为场解决方案"单选按钮,因为计时器作业需要执行比沙盒解决方案更高的信任级别。

图 3."SharePoint 自定义向导"对话框

"SharePoint 自定义向导"对话框

在"SharePoint 自定义向导"对话框中单击"完成"之后,Visual Studio 将创建并打开项目,如图 4 所示。创建项目后,您可以开始添加构成 SharePoint 计时器作业的基础所需的类。下一节概述如何创建这些类。

图 4. Visual Studio 中打开的新 SharePoint 项目

Visual Studio 中打开的新 SharePoint 项目

创建 SharePoint 计时器作业

包括随 SharePoint 安装的所有计时器作业均是通过 SPJobDefinition 类创建和执行的。要创建新的 SharePoint 计时器作业,首先必须向继承自 SPJobDefinition 类的项目添加一个类。

向您的项目添加类

  1. 右键单击项目,然后从上下文菜单中选择"添加"、"类"以打开"添加新项"对话框。

  2. 指定类的名称,然后单击"添加"。Visual Studio 将在文本编辑器中打开新类。

  3. 将类的可见性更改为 public,并使该类继承自 SPJobDefinition 类。

以下代码段显示继承自 SPJobDefinition 类的一个类的示例。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint;

namespace MonitoringJob {
    public class MonitoringJob : SPJobDefinition {
        public MonitoringJob() : base() { }

        public MonitoringJob(string jobName, SPService service)
            : base(jobName, service, null, SPJobLockType.None) {
            this.Title = jobName;
        }

        public override void Execute(Guid targetInstanceId) {
            // Put your job's code here.
        }
    }
}

在该代码段中,MonitoringJob 类继承自 SPJobDefinition 类,定义一个非默认构造函数,并重写基类的 Execute 方法。非默认构造函数是必需的,因为 SPJobDefinition 类的默认构造函数仅供内部使用。在创建您的构造函数时,您必须将表 1 中介绍的四个参数的值传递到基类构造函数。

表 1. SPJobDefintion 构造函数的参数

名称

说明

name

作业的名称。

service

拥有此作业的 SPService 类的实例。只有运行 SPService 对象表示的服务的服务器可以运行此作业。

server

与此作业相关联的 SPServer 类的实例。如果此作业未关联到特定服务器,则传递 null。

lockType

SPJobLockType 值表示哪些情况下可以同时运行多个作业实例。

在上个代码段中,null 作为 server 的值传递,因为此作业未关联到特定服务器。SPJobLockType.None 作为 lockType 的值传递以允许 SharePoint 同时运行多个作业实例。表 2 列出了可能的 SPJobLockType 值及其说明。

表 2. SPJobLockType 值

说明

None

锁定已禁用。作业将在服务器场中的所有服务器上运行,除非您为服务器参数传递 SPServer 对象。

ContentDatabase

将为关联到作业的 Web 应用程序的每个内容数据库运行作业。

Job

一次只能有一台服务器运行作业。

创建构造函数后,您必须重写 SPJobDefinition 类的 Execute 方法,并用您的作业所需的代码替换该方法中的代码。如果您的代码可以在没有其他配置的情况下运行,则您已完成创建此类。否则,您必须向您的项目添加配置屏幕和类,如下节中所示。下一节同样将讨论属于 Execute 方法的示例中的实际代码。

启用 SharePoint 计时器作业配置

若要存储作业的配置数据,请创建类以包含该配置并将其存储在 SharePoint 中。首先,该类必须继承自 SPPersistedObject 类。其次,该类中的字段必须是公共的(标记有 [Persisted] 属性),且具有内置的数据类型(Guid、int、string 等),继承自 SPAutoSerializingObject 的数据类型,或属于包含某个内置类型或继承自 SPAutoSerializingObject 的类型的集合类型的数据类型。仅保存了字段,而未保存属性,您将对象序列化为 XML 时可能对此习惯了。以下代码段显示用于配置 MonitoringJob 类的两个类。

using Microsoft.SharePoint.Administration;
public class MonitoringJobSettings : SPPersistedObject {
    public static string SettingsName = "MonitoringJobSettings";

    public MonitoringJobSettings() { }
    public MonitoringJobSettings(SPPersistedObject parent, Guid id) :
        base(SettingsName, parent, id) { }

    [Persisted]
    public string EmailAddress;
}

在该代码段中,MonitoringJobSettings 类用于配置 MonitoringJob 类。后者继承自 SPPersistedObject 并具有一个名为 EmailAddress、标记有 [Persisted] 属性的字段。EmailAddress 字段用于所发送电子邮件的收件人。

需要注意的一个细节是,MonitoringJobSettings 类定义了两个构造函数;一个默认构造函数,这是所有可序列化的类所需的,另一个是可对其基类调用构造函数的构造函数。第二个构造函数会传入 SPPersistedObject 的名称,充当 SPPersistedObject 对象的父项的 MonitoringJobSettings 的实例,以及用于在 SharePoint 中为其分配唯一标识符的 Guid。因为 MonitoringJob 与特定的 SPService 对象相关联,所以将同一 SPService 对象保存到 SharePoint 时,该对象将成为 MonitoringJobSettings 对象的父项。本节后面的部分提供了有关此工作方式的详细信息。

为作业及其配置创建类之后,您可以使用以下代码段将作业的配置保存到 SharePoint。稍后,您可将此代码添加到在激活包含您的计时器作业的功能时执行的事件处理程序。

// Get an instance of the SharePoint Farm.
SPFarm farm = SPFarm.Local;

// Get an instance of the service.
var results = from s in farm.Services
    where s.Name == "SPSearch4"
    select s;

SPService service = results.First();

// Configure the job.
MonitoringJobSettings jobSettings = new MonitoringJobSettings(service, 
    Guid.NewGuid());
jobSettings.EmailAddress = "myemail@demo.com";
jobSettings.Update(true);

在该代码段中,将获取表示 SharePoint Search Service 的 SPService 对象的引用,然后将该引用与唯一的 Guid 一起传递给 MonitoringJobSettings 类的构造函数。此后,将配置该类的 EmailAddress 属性,并调用该类的 Update 方法以便将对象保存到 SharePoint。将 true 传递给 Update 方法会指定您希望 SharePoint 覆盖任何已保存的现有配置。否则,会引发异常。

若要检索您的配置,请获取 SPService 的实例,调用其 GetChild 方法,然后传入要检索的类类型以及设置名称。以下代码段显示 SPJobDefinition 派生的类的 Execute 方法的部分实现。

public override void Execute(Guid targetInstanceId) {
    MonitoringJobSettings jobSettings =
        this.Service.GetChild<MonitoringJobSettings>(
            MonitoringJobSettings.SettingsName);

    if (jobSettings == null) {
        return;
    }

    // Code omitted.
}

MonitoringJobSettings 类是通过调用作业的父 SPService 对象的 GetChild 方法来从 SharePoint 中检索的。如果之前没有将任何内容保存到 SharePoint,则调用 GetChild 方法将返回 null。在您拥有作业的配置实例后,Execute 方法中的其余代码即可运行。

部署计时器作业

在创建作业和配置类之后,您必须添加一项 SharePoint 功能以使您的 SharePoint 管理员能够使用 SharePoint 中的功能。SharePoint 功能是在 XML 中编写的一组设置说明,可指示 SharePoint 在激活功能时执行的操作。可通过单击您网站的"网站设置"页上的"网站功能"或"网站集功能"链接来查看示例功能的列表。

向您的项目添加功能

  1. 右键单击"功能"文件夹,从上下文菜单中选择"添加功能"。

    图 5. 添加了新功能

    添加了新功能

  2. 在顶部的两个文本框中键入用户友好的标题和说明。您为标题和说明指定的值显示在 SharePoint 管理中心中的"Web 应用程序功能"页上。

  3. 因为该功能向您的服务器场中的某个 Web 应用程序注册作业,所以请将"范围"设置为"Web 应用程序"。

  4. 单击工具栏上的"保存"按钮。

在创建和配置功能之后,您必须向该功能添加事件接收器,以便您能够添加注册您的作业所需的代码。事件接收器是当 SharePoint 中发生特定事件时会运行代码的类。在本例中,您添加一个事件接收器以在激活或停用功能时运行代码。若要添加事件接收器,请右键单击您的功能,然后从上下文菜单中选择"添加事件接收器"。

添加事件接收器之后,您必须取消注释 FeatureActivated 和 FeatureDeactivating 方法。您可以删除其他方法,因为这些方法没有使用。接下来,您必须在 FeatureActivated 方法中添加代码以向 SharePoint 注册作业。最后,在 FeatureDeactivating 方法中添加代码以撤消注册作业。以下代码示例演示如何注册和撤消注册 MonitoringJob 对象。

public override void FeatureActivated(
    SPFeatureReceiverProperties properties) {

    // Get an instance of the SharePoint farm.
    SPFarm farm = SPFarm.Local;

    // Get an instance of the service.
    var results = from s in farm.Services
                  where s.Name == "SPSearch4"
                  select s;

    SPService service = results.First();

    // Remove job if it exists.
    DeleteJobAndSettings(service);

    // Create the job.
    MonitoringJob job = new MonitoringJob(
        MonitoringJob.JobName, service);

    // Create the schedule so that the job runs hourly, sometime 
    // during the first quarter of the hour.
    SPHourlySchedule schedule = new SPHourlySchedule();
    schedule.BeginMinute = 0;
    schedule.EndMinute = 15;
    job.Update();

    // Configure the job.
    MonitoringJobSettings jobSettings = new MonitoringJobSettings(
        service, Guid.NewGuid());
    jobSettings.EmailAddress = "myemail@demo.com";
    jobSettings.Update(true);
}

public override void FeatureDeactivating(
    SPFeatureReceiverProperties properties) {

    // Get an instance of the SharePoint farm.
    SPFarm farm = SPFarm.Local;

    // Get an instance of the service.
    var results = from s in farm.Services
                  where s.Name == "SPSearch4"
                  select s;

    SPService service = results.First();

    DeleteJobAndSettings(service);
}

private void DeleteJobAndSettings(SPService service) {
    // Find the job and delete it.
    foreach (SPJobDefinition job in service.JobDefinitions) {
        if (job.Name == MonitoringJob.JobName) {
            job.Delete();
            break;
        }
    }

    // Delete the job's settings.
    MonitoringJobSettings jobSettings =
        service.GetChild<MonitoringJobSettings>(
            MonitoringJobSettings.SettingsName);
    if (jobSettings != null) {
        jobSettings.Delete();
    }
}

在上一个代码示例中,FeatureActivated 方法通过访问 SPFarm 类的本地静态属性来获取 SPFarm 对象的实例。此后,将枚举 SPFarm 类的 Services 属性,以获取表示 SharePoint Search Service 的 SPService 实例。

接下来,如果作业已存在,则 FeatureActivated 方法会调用 DeleteJobAndSettings 方法来删除作业。如果之前已部署功能但在停用期间遇到问题,则作业可能已存在。此后,将通过传入作业的名称和 SPService 类的实例来创建作业定义的实例。在创建作业之后,您必须将其 Schedule 属性设置为表 3 中介绍的某个 SPSchedule 类的实例。

表 3. SPSchedule 类类型

类型

说明

SPMinuteSchedule

每 x 分钟运行一次作业。此类可用于安排小时、日、周、月或年以外的一段时间的作业。例如,若要每 11 天运行一次作业,请使用此类并将其 Interval 属性设置为 15840 分钟。

SPHourlySchedule

每小时运行一次作业。

SPDailySchedule

每天运行一次作业。

SPWeeklySchedule

每周运行一次作业。

SPMonthlySchedule

每月运行一次作业。

SPYearlySchedule

每年运行一次作业。

在上一个代码示例中,SPHourlySchedule 类用于每小时运行一次作业。以 Begin 和 End 开头的属性分别指定作业可以开始的最早和最晚时间。定时服务会在此间隔内随机选择开始作业的时间。设置您作业的 Schedule 属性后,调用作业的 Update 方法以向 SharePoint 注册它。方法中的最后一步是创建 MonitoringJobSettings 类的实例,设置其属性,然后通过调用其 Update 方法来保存它。

在 FeatureDeactivating 方法中,调用了 DeleteJobAndSettings 方法来删除之前注册的作业。DeleteJobAndSettings 方法使用 JobDefinitions 属性获取为此 SPService 对象注册的作业的列表,并删除该功能之前创建的作业。该方法还会获取作业的配置并将其删除。

此时,即可测试您的代码。在下一节中,您将了解如何测试和调试您的 SharePoint 作业。

测试和调试 SharePoint 计时器作业

调试 SharePoint 代码时,您通常将项目的生成类型设置为"调试",然后按 F5 调试该项目。Visual Studio 会编译您的代码,将生成的程序集和 XML 文件打包到 SharePoint 解决方案包 (.wsp) 文件,然后将该解决方案包部署到 SharePoint。在部署解决方案包之后,Visual Studio 将激活您创建的功能。

调试计时器作业

  1. 若要在 SharePoint 中调试计时器作业,您必须附加到 SharePoint 定时服务后面的进程。若要附加到 SharePoint 定时服务,请从菜单栏中选择"调试",然后选择"附加到进程"。

  2. 在"附加到进程"对话框中,确保对话框底部的两个复选框均处于选中状态,然后从"可用进程"列表中选择"OWSTIMER.EXE"。

    图 6."附加到进程"对话框

    "附加到进程"对话框

  3. 单击"附加"以完成附加到 SharePoint 定时服务。

    现在您可以在您的作业代码中添加断点。

若要使作业立即运行,您可以发出将引起 SharePoint 定时服务立即运行您的作业的 Windows PowerShell 命令。若要打开 Windows PowerShell,请单击"所有程序",单击"Microsoft SharePoint 2010 产品",然后选择"SharePoint 2010 Management Shell"。

随即打开 Windows PowerShell 控制台,其中包含已注册的 SharePoint 命名空间。在一行中键入以下命令,然后按 Enter 安排您的作业立即执行。

Get-SPTimerJob "jobname" -WebApplication "url" | Start-SPTimerJob

在命令行中,jobname 是您项目的名称,而 url 是您 Web 应用程序的 URL。Get-SPTimerJob 命令可获取您作业的作业定义,而竖线 (|) 会将作业定义发送给 Start-SPTimerJob 命令,而这将会安排运行它。SharePoint 定时服务通常需要不到 30 秒即可完成运行。如果它未执行,请确保调试程序在 Visual Studio 中未暂停。

结论

计时器作业使您可以灵活地从您的 Internet Information Services (IIS) 网站中卸载长时间运行的或计划的进程。计时器作业的功能很强大,因为可对计时器作业进行配置以按特定的计划运行,且计时器作业可以提供为企业创建一流的、基于 SharePoint 的解决方案所必需的任何功能。

关于作者

Bryan Phillips 是 Composable Systems, LLC 的高级合伙人,并且是 SharePoint Server 领域的 Microsoft 最有价值的专家。他是 Professional Microsoft Office SharePoint Designer 2007 and Beginning SharePoint Designer 2010(《专业化的 Microsoft Office SharePoint Designer 2007 和入门级 SharePoint Designer 2010》)的合著者,并且开设有与 SharePoint 有关的博客。Bryan 自 1997 年起一直从事 Microsoft 技术的研究,拥有 Microsoft 认证培训师 (MCT)、Microsoft 认证解决方案开发人员 (MCSD)、Microsoft 认证数据库管理员 (MCDBA) 和 Microsoft 认证系统工程师 (MCSE) 认证。

下面是来自 Wrox 的有关 Microsoft SharePoint 2010 文章的技术编辑:

  • Matt Ranlett 是一名 SQL Server MVP,多年来他一直是亚特兰大 .NET 开发人员社区的固定成员。作为 Atlanta Dot Net Regular Guys 创始成员之一的 Matt 创立并领导多个地区的用户小组。Matt 工作之余的大部分时间都花在当地和国内社区活动(例如 SharePoint 1, 2, 3! 系列)上,并且组织过三届亚特兰大代码挑战营 (Code Camp),以技术副总裁身份入主 INETA 董事会,并现身多个播客(如 .Net Rocks 和 ASP.NET 播客),最近他终于能够抽出时间与美丽的 Kim 女士喜结连理,Matt 帮助 Kim 饲养了三只怪物狗。Matt 目前是 Intellinet 的高级顾问,致力于帮助人们通过交付能够创建商业价值的创新型解决方案来取得成功。

  • Jake Dan Attis。在谈到有关 SharePoint 开发的模式、惯例和调控时,不得不提 Jake Dan Attis。Dan 是从加拿大蒙古顿移居到美国亚特兰大的移民,他拥有应用数学学位,但却是一名不折不扣的绝杆 SharePoint 开发人员。您经常会发现 Dan 参加和组织亚特兰大地区的社区活动并发表演讲,其中包括代码挑战营、SharePoint Saturday 以及亚特兰大 SharePoint 用户小组。当他不在 Visual Studio 中工作时,Dan 很喜欢与他的女儿 Lily 在一起,观看曲棍球和足球比赛,并品尝啤酒的美味。

  • Kevin Dostalek 拥有 15 年以上的 IT 行业从业经验和 10 年以上管理大型 IT 项目及 IT 人员的经验。他曾领导各种规模的公司开展过项目,并担任过各种角色,包括开发人员、架构师、业务分析师、技术负责人、开发经理、项目经理、程序经理和导师/指导者。除这些角色外,在 2005 年至 2008 年期间,Kevin 还以副总裁身份管理过一个中等规模 MS 金牌合作伙伴的解决方案交付部门,此后还担任过革新和教育部门的副总裁。2010 年年初,Kevin 成立了 Kick Studios 公司,提供 SharePoint 和社会计算专门领域的咨询、开发和培训服务。此后,他还以演讲者身份现身于全国各地的各种用户小组、峰会和大会类型的活动中。您可以在 Kevin 的博客上了解有关他的更多信息。

  • Larry Riemann 拥有 17 年以上为世界上的一些大型公司构建和创建业务应用程序的经验。Larry 是一名独立顾问,拥有 Indigo Integrations,并且专门通过 SharePoint911 提供 SharePoint 咨询。他是一名作者,为刊物撰写文章,有时也在各种大会上发表演讲。最近几年,他的工作重点是 SharePoint,主要创建和扩展能够补充 SharePoint 之不足的功能。除了研究 SharePoint,Larry 还是一名颇有造诣的 .Net 架构师,在系统集成、企业体系结构和高可用性解决方案领域有丰富的经验。您可以在他的博客上与他联系。

  • Sundararajan Narasiman 是位于印度金奈的 Cognizant Technology Solutions 的内容管理和门户小组的一名技术架构师,拥有 10 多年的行业从业经验。Sundararajan 主要从事 SharePoint 2010 Server 堆栈和主流 .NET 3.5 开发方面的体系结构和技术咨询工作。他热衷于编程工作,并且对极限编程 (Extreme Programming) 和 TDD 有着浓厚的兴趣。

其他资源

有关详细信息,请参阅以下资源: