协作工作流

在 SharePoint 2010 改进

Paul Andrew

SharePoint 2007 引入的协作应用程序的工作流,许多组织都有会通过移动到 SharePoint 工作流的手动过程。 为什么在软件设计中使用工作流,我们将主要原因是管理长时间运行的进程。 而计算机硬件设计完成进程作为可能的等待完成表单的人快速做出决策,或共享的外部的操作的结果总是花费更长的时间比以使 CPU 处于繁忙状态所需的毫秒响应时间。 SharePoint 工作流是软件的自动进行这些手动流程,以前所需的纸张或使用复杂可以记录和监视长时间运行的任何活动的理想的方法。

Windows 流 Foundation 在 2005 年第一次引入和最初包含在 Microsoft.NET Framework 3.0 中。 今天,SharePoint 2010 提供了许多新改进的工作流开发人员,并在 SharePoint 2007 中的工作流的普及上生成。 对于长时间运行人类工作流位置我们经常等待完成任务的人员建议 SharePoint 工作流。 本文将向您介绍关键概念并描述了可用新的功能。 首先,我将谈论 SharePoint 2010 中新功能的工作流开发人员,我将在然后遍历几个新用户方案。

工作流模型设计工具改进

SharePoint 2010 提供更好地适合那些创建和维护工作流模型的需求加工中更多的选项。 工作流开发的工具包括 Visual Studio 2010、 SharePoint 设计器 2010年和 Visio 2010。

应当注意的是 SharePoint 2010 需要.net Framework 3.5。 下一个版本的.net Framework 4.0 目前正在开发中但产品时间线意味着 SharePoint 2010 不是依赖于它。

visual Studio 2010 包括许多加工改进为专门针对工作流项目的 SharePoint 项目。 新的 SharePoint 解决方案 (WSP) 包装可帮助部署您轻松地到将允许您将 ASPX 工作流启动和关联表单添加到 Visual Studio 2010 工作流项目 ( 的 图 1) 下的 SharePoint 服务器的工作流。 在本文中稍后介绍的一个演练演练中我将向您展示如何添加一个启动窗体。


图 1 的 Visual Studio 2010 SharePoint 项目模板

SharePoint 设计器 2010年还具有新的图形化的工作流设计器设计工作流和直接到 SharePoint 部署它们。 它还之前可以使用作为原型设计工具中 Visual Studio 2010 进一步开发工作流。

在设计器 2010 SharePoint 中的另一改进是它现在允许您编辑附带 SharePoint 出的-更改工作流。 它也将使用 InfoPath 表单如果安装了 InfoPath 或在 Data Form Web Part 如果未安装 InfoPath ; 以前,仅 ASPX 窗体已由 SharePoint 设计器 2007年。 现在可以使用 InfoPath 表单,因为它可以很容易非常编辑这些稍后使用以提高它们的 InfoPath 表单。 如果指定工作流中的新列它们将自动添加到列表中将与工作流相关联的架构。 这些称为关联列,并且可以在整个 SharePoint 设计器工作流中使用。 可以将用户配置文件数据绑定到可以获取有关 SharePoint 用户配置文件的信息使工作流中的属性。 渚嬪,您可以查找为审批直接管理器的名称。

SharePoint 设计器 2010年包括一个新的任务进程设计器创建工作流中的活动,但可以灵活地管理所有内的一次活动在审批流程的方式。 这包括定义定义审批要求和如果基础文档更改在审批期间发生的情况的语义的委派的升级进程。

工作流模型进行进一步编辑在 SharePoint 设计器 2010 Visio 2010 中创建。 Visio 2010 支持业务流程建模表示法。 它还支持 sub-processes 和分解关系图和验证分析以确保正确构造一个关系图的容器。

在 SharePoint 2010 中的新工作流模型

站点工作流

站点工作流释放从要求列表项目或文档项运行针对工作流工作流开发人员。 这可用于当实现工作流过程不能启动作为列表项或文档的结果。 这是开发人员将只是要添加工作流创建虚拟的列表和项以这样一个常见方案。 在可视化的 Studio 2010 您只需选择网站流 的 图 2 所示创建工作流项目项时。


图 2 的 站点/列表工作流对话框页

可以通过从 SharePoint 中网站操作菜单中选择网站工作流来获取已激活的网站工作流。 它可以显示工作新流可以启动任何正在运行的网站的工作流和已完成的工作流。 因为站点工作流 don’t 具有列表项目或文档从启动,它们必须手动启动通过 SharePoint 用户界面或通过 SharePoint API。

可重用声明式工作流

在 SharePoint 设计器 2010,您可以创建可重用的声明性工作流。 在 SharePoint 2007 在 SharePoint 设计器中创建一个工作流模型只可能与一个列表相关联。 这些可重用的工作流不依赖于特定的列表,但可以与任何列表相关联。 可重复使用工作流设计,并将其与多个列表相关联。 此外,另存为模板命令可用于创建一个包含可重用的工作流可以被移动到另一个 SharePoint 服务器或者 Visual Studio 2010 到其中的 WSP 文件。 在 SharePoint 设计器中,这意味着您 don’t 具有访问数据,因为没有特定的列表结构已连接的列表域的访问权限。

运行库和宿主改进

高特权工作流

在 SharePoint 2007 中工作流作为登录用户的身份运行。 在 SharePoint 2010 具有高特权可以指定的帐户运行工作流,以使其具有附加的工作流,需要的权限 (请参阅 的 图 3)。 创建工作流在 SharePoint 设计器 2010年时, 可以添加个别步骤,使其运行为而不是登录的用户的工作流的作者。


图 3 的 显示高的特权模拟步骤的 SharePoint 设计器工作流

SPTimer 位置

SharePoint 根据上次的操作的两个位置之一中执行工作流实例。 如果工作流中的最后一个操作正在等待用户输入,工作流继续执行上 Web 前端用户完成该输入的位置。 如果工作流续从延迟计时器或从其他地方接收事件,则它将执行 SPTimer 服务中。 使用 SharePoint 管理中心中的新选项,您现在可以设置首选的服务器 SPTimer 服务运行的位置。 若要执行此操作单击 SharePoint 管理中心的应用程序管理部分的管理内容数据库菜单中。 然后单击上内容的数据库和向下滚动到首选服务器的计时器作业的设置 (如 的 图 4 所示)。 可以手动停止 SPTimer 服务 don’t 希望其运行的任何服务器上。


图 4 的 首选服务器的工作流计时器作业的设置

工作流消息的改进 

SharePoint 2010 添加列表基于工作流的四个新工作流事件接收器。 启动、 已启动、 Postponed 和已完成 (如 的 图 5 所示),都是在四个工作流事件接收器可用。 这些是类似于其他 SharePoint 事件接收器和它们在响应该事件在服务器上执行代码。 若要使开发更容易,Visual Studio 2010 包括使使用相当简单这些事件的事件接收器的项目类型。 新的事件将附加到特定的列表,并触发与该列表这意味着这些事件接收器 can’t 激发上站点的工作流相关联的工作流实例在发生事件时。 事件接收器还要求列表。


图 5 的可以在 Visual Studio 2010 能生成的事件接收器

SharePoint 2007 进行简单涉及在工作流,中的人,但被难发送和接收与外部系统的邮件。 建议的方法就是使用任务项来将消息发送到外部 Web 服务使用的系统并具有外部的系统更新任务,使其返回的结果。

SharePoint 2010 添加可插入的工作流服务的支持。 这些将是为 Windows 流基础 (WF) 开发人员所熟悉,并且通过创建包含方法和事件接口定义。 此接口连接到一对称为 CallExternalMethod 和 HandleExternalEvent 的活动。 一种工具附带 WF 在.NET Framework Framework中称为 WCA.exe 生成强类型用于发送和接收基于该接口上的活动。 这些生成的活动可以也使用 SharePoint 工作流中。 它们不需要作为属性设置接口,而是可以被拖动直接从工具箱到工作流设计曲面图。

由工作流程集成了与 SharePoint 工作流服务代码加载到 gac 中的访问。 它需要从 SPWorkflowService 基类继承,并且它需要在 web.config 中引用。

将使用这些新的活动可以异步消息发送到外部系统从 SharePoint 工作流内右。 我将研究创建和使用在第二个演练本文中稍后介绍的这些活动。

本演练的构建简单的工作流在 Visual Studio 2010

在 SharePoint 工作流中关键的事情是交互人员,以便最简单的做法是将任务分配给某个人,并等待他们响应。 以下内容,则显示新的 Visual Studio 2010 SharePoint 工具如何使该任务分配真正易于生成。

步骤 1-创建新的 SharePoint 顺序工作流项目

创建新的 SharePoint 工作流项目是很容易的。 在 的 图 1 所示以前,请选择新的项目模板选择器上的顺序工作流。 这还可以使用状态机工作流样式来完成。

新的工作流项目向导已经有四页。 第一个是 SharePoint 的所有工具项目模板都具有共同的页面,您希望使用部署和调试您的解决方案, 的 图 6 所示位置标识本地的 SharePoint 网站的 URL。


图 6 的 首页的新建的工作流项目向导

第二个是一个页,其中提供工作流的名称,选择是否将其与列表或作为站点关联。 前面 的 图 2 显示此页。

第三页是您决定如果 Visual Studio 将自动为您关联工作流,或者可以在已部署后手动执行。 如果您选择将保留选中框,它已为列表 (如果您以前选择基于列表的工作流) 相关联、 工作流历史记录列表,以使用和任务列表用于选择选项 (请参阅 图 7) 。 通常,历史记录和任务列表中不需要更改。


图 7 的 第三页的新建的工作流项目向导

第四个和最后一页,可以选择如何 (请参阅 的 图 8) 启动工作流。  您不应取消选择所有三个这些或您的工作流将会很难进行启动。 对于站点工作流可以只选择手动启动工作流。 为基于列表的工作流也可以选择在创建文档时启动工作流实例或更改文档时启动。


图 8 的 第四页的新建的工作流项目向导

新的空白的工作流模型如下所示 Visual Studio 2010 在设计图面中的 图 9。 激活的工作流活动从 HandleExternalEvent 活动派生,并提供了从 SharePoint 到工作流实例初始化数据。 我将稍后涉及多个 HandleExternalEvent 活动。


图 9 的 显示的 WorkflowActivated 活动的默认空白工作流

步骤 2 — 发起表单添加到该工作流

当它们在启动工作流时,可以向用户显示一个启动窗体。 它允许工作流,以获取在开始之前收集参数。 这可以添加在 Visual Studio 2010 轻松地在工作流项目在解决方案资源管理器中右键单击,然后选择添加然后新的项,如 的 图 10 所示。 选择工作流启动表单模板和新的窗体是自动与工作流相关联。 它是您编辑 HTML 中的 ASPX 窗体 (请参阅 的 图 11)。


图 10 添加工作流启动表单

调用 GetInitiationData 的一种方法需要在代码隐藏 ASPX 文件中进行编辑。 此方法只返回一个字符串 ; 如果多个值则建议您序列化它们到 XML 片段返回它们之前。 一旦工作流实例正在运行,可以很容易地获得对此字符串只是通过引用 workflowProperties.InitiationData。 多个值需要它们时,序列化 GetInitiationData 中如果将 de-serialized 从 XML 片段。


图 11 的 默认工作流 ASPX 启动窗体

启动窗体将添加一个文本域,然后从 GetInitiationData 方法返回该字段。 在下面的代码中标记添加第一个 asp: 内容标记内, 就像这样:

<asp:TextBox ID="MyID" runat="server" /> <br />

GetInitiationData 方法已存在,只需要有代码添加到返回 MyID.Text 属性。 下面的代码显示了已更新的方法代码:

private string GetInitiationData()
{
  // TODO: Return a string that contains the initiation data that will be passed to the workflow. Typically , this is in XML format.
  return MyID.Text;
}

第 3 步 – 添加工作流日志活动

LogToHistoryList 活动是非常易于使用。 创建每个工作流实例有可以在 SharePoint 用户界面中显示一个历史记录列表。 活动采用单个字符串参数,并将项添加到该列表中。 它可用于在生产中向用户报告的工作流实例状态。 只需将 LogToHistoryList 活动从工具箱拖动到工作流设计和说明属性设置 (请参阅 的 图 12)。


图 12 的 显示 SharePoint 工作流活动的 Visual Studio 工具箱

在工作流中的属性称为依赖项属性。 这些在运行时绑定到另一个活动属性、 字段、 属性或方法。 此过程通常称为布线,它是什么允许即使它们 don’t 具有特定类型信息彼此在编译时,一起工作流中的活动。 在 Visual Studio 中属性窗口中的每个属性有线类的字段或在工作流类的类属性。 字段是最容易创建和弹出布线的向上为创建新字段、 创建新的属性或向现有的布线允许工作流属性对话框。


图 13 的 要创建的字段绑定的依赖项属性

图 13 显示添加新字段具有默认名称。 以下内容显示到为该属性设置为工作流启动数据活动 MethodInvoking 的事件处理程序添加的代码:

public String logToHistoryListActivity1_HistoryDescription1 = default(System.String);

private void logToHistoryListActivity1_MethodInvoking(object sender, EventArgs e)
{
  logToHistoryListActivity1_HistoryDescription1 = workflowProperties.InitiationData;
}

因为此属性 doesn’t 连接活动,之间,但若要了解有关依赖项属性的一点是很好的简单活动,实际上可以直接在代码中设置 HistoryDescription 属性。

第 4 步 – 添加 CreateTask 活动

此下一步是称为 SharePoint 任务项的人工工作流程交互的主要部分。 创建任务、 分配给一个人,然后等待人对该任务所做的更改。 CreateTask 活动必须拖动到工作流程设计图面上,并将它们然后配置了所有必需的属性。 图 14 显示 CreateTask 的属性窗口,只需后对其拖动到活动。


图 14 的 显示的 CreateTask 活动的属性窗格

首先需要在此处为该任务的相关标记。 相关标记用于在工作流中的消息相关。 它提供了使任务对象特定的工作流实例中和在 SharePoint 中的工作流运行库之间映射的唯一标识符。 这用于,以便 SharePoint 接收工作流实例的消息时它可以找到正确的工作流实例内正确的任务。 必须配置 CorrelationToken 属性,并且它不推荐使用该 WorkflowToken 的任务,虽然这 isn’t 禁止在工具。 输入 TaskToken 并按输入的新名称的相关标记。 然后展开 (+) 出现,并单击移到右侧 OwnerActivityName 的拖放并选择工作流符号。

必须配置在 TaskId 以及新的 GUID 指定的任务 id。 这是通过选择 TaskId 属性,然后单击该 […] 以调出属性编辑器的省略号。 单击绑定到新的成员选项卡,选择创建的字段,然后单击确定。 相同必须完成 TaskProperties 属性通过再次选择属性,单击省略号上添加新字段。 接下来,双击新的 CreateTask 活动,调出 createTask1_MethodInvoking 处理程序代码,并在代码中设置属性工作流在设计图面上。

新的任务必须给定一个标题和对于良好的度量值将任务描述设置到字符串中我收到从启动窗体。 一旦所有这些属性已被将设置这是添加的代码:

public Guid createTask1_TaskId1 = default(System.Guid);
public SPWorkflowTaskProperties createTask1_TaskProperties1 = new
  Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();

private void createTask1_MethodInvoking(object sender, EventArgs e)
{
  createTask1_TaskId1 = Guid.NewGuid();
  createTask1_TaskProperties1.Title = "Hello";
  createTask1_TaskProperties1.Description = workflowProperties.InitiationData;
}

步骤 5 – 添加该 OnTaskChanged 和 CompleteTask 活动

使用该时来等待的任务的多个更改,直到看到所需的更改的活动。 在 While 活动必须包含如 OnTaskChanged 活动的另一个活动。 侦听活动还可用于通过添加侦听分支内的实际事件接收器活动与一个侦听活动侦听的一次多个事件。 鎴栬 € 咃,您可以只是等待,直到与 OnTaskDeleted 活动中删除任务。

常见的要求是逐步升级或等待事件超时。 这是通过使用侦听活动侦听这两个任务使用延迟活动更改消息和计时器消息。 第一条消息,以接收的任何一个包含该工作流和其他活动停止等待活动简历。 延迟活动在超时发生时发送一条消息。

有很多上面描述的选项,但最简单是使用 OnTaskChanged 将等待任务项的任何更改,然后继续。 要配置该 OnTaskChanged,需要在 CorrelationToken 和 TaskId 属性向上连结到作为该 CreateTask 相同的域。

上次,添加 CompleteTask 活动和重新设置 CorrelationToken 和 TaskId 属性。 的 图 15 所示等待消息的活动是绿色的而将消息发送的活动是蓝色。 这是在 SharePoint 工作流的整个内保持一致。


图 15 的 已完成的简单任务流模型

步骤 6 – 部署和测试工作流

现在工作流是几乎完整的因此按 f5 键,并等待部署。 按 F5 将编译工作流、 打包到一个 WSP 的工作流、 到 SharePoint 部署该 WSP、 激活 SharePoint 功能、 Visual Studio 2010 调试器附加到 SharePoint 并启动 Internet Explorer 与 SharePoint 网站。

一旦出现在 SharePoint 网站,请从网站操作菜单上选择网站工作流。 您将看到所有的站点工作流,并且您可以单击上您启动它。 选中后它将会看到您的工作流启动表单 的 图 16 所示。


图 16 的 工作流启动表单

其他改进可以添加到此基本初学者工作流模型使用内容类型定义分配给一个人使用电子邮件以通知用户他们已被指派一个任务的任务和甚至使用来创建更复杂的窗体为完成电子邮件中或联机用户的 InfoPath 表单等。

本演练的构建可插入的工作流服务

新 SharePoint 2010 中是可插入的工作流服务添加到 SharePoint 能力。 这始终已可能在 Windows 流基础,但 SharePoint 承载工作流运行时已锁定状态,以前 didn’t 允许这样。 主要可插入的工作流服务被设计为发送和接收消息超出了工作流实例。 但是,它们也是有价值的任何长时间运行系统操作 (如长时间运行计算。

这是工作流运行时将使用的消息传递归纳作为管理长时间运行的工作机制。 只需执行的活动内运行很短的工作,并长时间运行操作已完成或邮件接收,则表示一个人完成任务之前将一直挂起工作流。 因此等待响应人员,时工作流实例被冻结并不会占用 CPU 或 RAM 执行的服务器上的资源。 (冻结只需工作流实例的状态写入到数据库记录中 rehydrated 的回发,并稍后继续上一方法的方法。

所有类型的长时间运行的工作流由都处理相同的方式。 首先,它启动长时间运行的工作或发送一条消息,然后它挂起工作流直到完成长时间运行的工作或收到响应。 相关标记用于确保收到响应时恢复正确的工作流实例。

作为一个示例考虑两个常见的长时间运行的工作示例。 一个示例是同步的 Web 服务请求位置调用方将被阻塞,直到该通道上收到响应。 这不是适合于工作流活动内运行。 工作流服务需要等待 Web 服务调用完成,然后为发送的邮件重新与响应一起工作流实例。 另一个示例是需要运行一个 CPU 密集的工作项,但因为它可能要花较长的时间比第二个需要运行之外的工作流活动。 再次,您可以使用工作流服务并在工作流服务执行 CPU 密集的工作项中创建线程。 回它完成后,新的线程可以发送消息。

这些示例的两个实现具有相同的模式。 下面的演练演示如何创建新的 SharePoint 顺序流和调用因素来确定多少素数有下 100,000,000 素数一个可插入的工作流服务。 此项工作要花很长时间执行活动的主行内。

第 1 步 – 创建可插入的工作流服务

在 Visual Studio 2010 创建可插入的工作流服务,需要作为接口和类在项目中的实现服务。 图 17 显示了一个可插入的工作流服务,它可以将添加到您的项目称为 MyService.cs 新的类文件中的一个示例。 在代码中接口定义是在 IMyService 中,该接口的实现类 MyService 和 MessageOut 方法中单独的线程上通过匿名方法委托运行大多数逻辑。 在单独的线程中对 RaiseEvent 调用将返回到等待 HandleExternalMessage 活动发送邮件。

图 17 的 可插入的工作流服务

// Interface declaration
[ExternalDataExchange]
public interface IMyService
{
  event EventHandler<MyEventArgs> MessageIn;
  void MessageOut(string msg);
}

// Arguments for event handler
[Serializable]
public class MyEventArgs : ExternalDataEventArgs
{
  public MyEventArgs(Guid id) : base(id) { }
  public string sAnswer;
}

// Class for state
class FactoringState
{
  public SPWeb web;
public Guid instanceId;
  public FactoringState(Guid instanceId, SPWeb web)
  {
    this.instanceId = instanceId;
    this.web = web;
  }
}

// Interface implementation
class MyService : Microsoft.SharePoint.Workflow.SPWorkflowExternalDataExchangeService,
                  IMyService
{
  public event EventHandler<MyEventArgs> MessageIn;
  public void MessageOut(string msg)
  {
    ThreadPool.QueueUserWorkItem(delegate(object state)
      {
        FactoringState factState = state as FactoringState;
        DateTime start = DateTime.Now;
        int topNumber = 100000000;
        BitArray numbers = new System.Collections.BitArray(topNumber, true);

        for (int i = 2; i < topNumber; i++)
        { if (numbers[i]) { for (int j = i * 2; j < topNumber; j += i)
          numbers[j] = false; } }
        int primes = 0; for (int i = 2; i < topNumber; i++)
        { if (numbers[i]) primes++; }

        string sAnswer = "Found " + primes + " in " +
          Math.Round(DateTime.Now.Subtract(start).TotalSeconds, 0) + " seconds";

        // Send event back through CallEventHandler
        RaiseEvent(factState.web, factState.instanceId, typeof(IMyService),
                   "MessageIn", new object[] { sAnswer });
      }, new FactoringState(WorkflowEnvironment.WorkflowInstanceId,
                            this.CurrentWorkflow.ParentWeb));
    }

    // Plumbing that routes the event handler
    public override void CallEventHandler(Type eventType, string eventName,
      object[] eventData, SPWorkflow workflow, string identity,
      System.Workflow.Runtime.IPendingWork workHandler, object workItem)
    {
      var msg = new MyEventArgs(workflow.InstanceId);
      msg.sAnswer = eventData[0].ToString();
      msg.WorkHandler = workHandler;
      msg.WorkItem = workItem;
      msg.Identity = identity;
      // If more than one event - you'd need to switch based on parameters
      this.MessageIn(null, msg);
    }
    public override void CreateSubscription(MessageEventSubscription subscription)
    { throw new NotImplementedException(); }
    public override void DeleteSubscription(Guid subscriptionId)
    { throw new NotImplementedException(); }

步骤 2 – 更新 web.config

一旦在构造可插入的工作流服务,它需要使用 SharePoint 中运行的工作流运行时进行注册。 这是通过编辑 web.config 部分中的工作流服务的。 应完成所需 web.config 编辑使用调用 SPWebApplication.WebConfigModifications.Add 一个功能接收器。 下面的代码显示了要添加附加的配置项:

<WorkflowServices><WorkflowService Assembly="WorkflowProject1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=YOURPUBLICKEY" Class="WorkflowProject1.MyService">
</WorkflowService></WorkflowServices>

可以使用 GACUTIL.EXE/l 获取程序集名称和公钥信息。

第 3 步 – 创建工作流模型

工作的其余部分是很容易的。 该工作流添加调用外部方法和处理外部事件的活动,并将其配置为指向此服务,如 的 图 18 所示。 调用外部方法活动将在服务中调用 MessageOut 和处理外部事件活动将等待事件 MessageIn。 这涉及每两个活动中设置 InterfaceType 和 EventName 属性。


图 18 的 使用可插入流服务的已完成工作流


图 19 完成计算可插入的工作流服务的上标符

步骤 4 – 运行工作流

当运行此工作流时,它将启动单独的线程进行质数计算可插入的工作流服务中。 10-15 秒的运行后, 工作流历史记录项出现在 中所示 图 19它显示了有 5,761,455 素数下 100,000,000。

如下所示,没有可插入的工作流服务为编写一些代码和编写为连接到每个系统的更多代码。 有两个选项用于减少了与外部服务通信所需的代码量。 一个是通过使用 BizTalk Server 并进行使用的连接其他系统的 BizTalk 适配器库的接口。 其他使用业务连接服务在 SharePoint 2010 其中提供了一种公开通过外部列表的其他系统中的数据的方式。

简单和成功

在 Visual Studio 2010、 SharePoint 设计器 2010年和 Visio 2010 新工具使 SharePoint 2010 流的开始使用,并能成功的开发人员更容易。 SharePoint 2010 工作流宿主中的新功能使 SharePoint 同时更强健和适用于解决更多种类的软件中的工作流出现问题。

工作流现在很容易构建和部署到使用标准 SharePoint WSP 文件的包装工具 Visual Studio 2010 附带的 SharePoint。 能够将部署到许多大型公司表示工作流中常见的标准 SharePoint 网站可以被采用更容易。 工作流在 SharePoint 中的方便地与通过任务和电子邮件的人构建长时间运行的进程进行通信。 在 SharePoint 中的工作流现在还便于通信与通过业务连接服务的可插入的工作流服务系统和 BizTalk Server。

可以从位于 blogs.msdn.com/pandrew 我的博客下载两个的演练,本文中的代码。

Paul Andrew 是在 Microsoft 的 SharePoint 一位高级技术产品经理。 他负责开发人员访问群体的 SharePoint。 在 2005 年,他已由 SAMS 发布该简介册"演示 Windows 流基础,"有关的潜在顾客作者。 他在计算机系统工程从 Massey 大学,新西兰,持有单身汉的技术,又有 MCSD、 MCSE 和 MCDBA 认证。