Windows Workflow学习文档
工作流:为了实现组织目标,有关业务活动依时序或逻辑关系相互连接构成业务流程。在业务开展过程中,文档、信息或任务,依据组织规范在参与者之间传递、处理或执行。业务流程中,实现了基于计算机自动化的全部或部分称为工作流。
工作流管理系统(WorkflowManagementSystem,WFMS):是定义、创建、执行工作流的系统。在最高层上,WFMS应能提供以下三个方面的功能支持:
? 建造功能:对工作流过程及其组成活动定义和建模;
? 运行控制功能:在运行环境中管理工作流过程,对工作流过程中的活动进行调度;
? 运行交互功能:指在工作流运行中,WFMS与用户(业务工作的参与者或控制者)及外部应用程序工具交互的功能。
工作流管理系统的基本结构
WFMS组成如图所示:
在这个一般结构模型中,有三种类型的部件:
? WFMS内提供各种功能支持的软件组元(用深色填充图形表示);
? 为一个或多个软件组元使用的各种系统定义和控制数据(未填充图形);
? 应用程序和数据库(浅色填充图形)。
系统中主要部件和数据的作用如下:
1.过程定义工具
过程定义工具被用来创建计算机可处理的业务过程描述。它可以是形式化的过程定义语言或对象关系模型,也可以是简单地规定用户间信息传输的一组路由命令。
2.过程定义
过程定义(数据)包含了所有使业务过程能被工作流执行子系统执行的必要信息。这些信息包括起始和终止条件、各个组成活动、活动调度规则、各业务的参与者需要做的工作、相关应用程序和数据的调用信息等。
3.工作流执行子系统(WES)和工作流引擎
工 作流执行子系统也称为(业务)过程执行环境,包括一个或多个工作流引擎。工作流引擎是WFMS的核心软件组元。它的功能包括:解释过程定义;创建过程实例 并控制其执行;调度各项活动;为用户工作表添加工作项;通过应用程序接口(API)调用应用程序;提供监督和管理功能等。工作流执行子系统可以包括多个工 作流引擎,不同工作流引擎通过协作共同执行工作流。
4.工作流控制数据
指被WES和工作流引擎管理的系统数据,例如工作流实例的状态信息、每一活动的状态信息等。
5.工作流相关数据
指与业务过程流相关的数据。WFMS使用这些数据确定工作流实例的状态转移,例如过程调度决策数据、活动间的传输数据等。工作流相关数据既可以被工作流引擎使用,也可以被应用程序调用。
6.工作表和工作表处理程序
工作表列出了与业务过程的参与者相关的一系列工作项,工作表处理程序则对用户和工作表之间的交互进行管理。工作表处理程序完成的功能有:支持用户在工作表中选取一个工作项,重新分配工作项,通报工作项的完成,在工作项被处理的过程中调用相应的应用程序等。
7.应用程序和应用数据
应用程序可以直接被WFMS调用或通过应用程序代理被间接调用。通过应用程序调用,WFMS部分或完全自动地完成一个活动,或者对业务参与者的工作提供支持。与工作流控制数据和相关数据不同,应用数据对应用程序来讲是局部数据,对WFMS的其他部件来说是不可见的。
从 图上我们可以看到3.0是以.Net Framework 2.0为核心,分别对不同技术和应用层面提供的一些模块。我记得一篇文章里面说到.Net Framework 3.0 不应该叫3.0更确切的叫.Net Framework 2.5(哈哈!不知道大家是否赞同这个说法)。
在.Net Framework 3.0包含了四个模块:
WPF(Windows Presentation Foundation):
WPF is a productive, unified approach to UI, Media, and Documents that you can use to deliver unmatched user experiences to your customers.
WPF提供了一个统一UI、媒体和文档的用户体验。
WPF统一了WinForm和Web的用户体验开发。
WCF(Windows Communication Foundation):
Unified framework for rapidly building service-oriented applications
WCF是一个迅速的建立SOA应用的框架。
WCF集成了WebService、Remotting和Com+的一些特征。
WF(Windows Workflow Foundation):
The Programming Model, Engine And Tools For Building Workflow Enabled Applications On WindowsPlatform.
在Windows平台上提供一个构建工作流程应用的模块、引擎和工具。
CardSpace(Windwos CardSpace):
Technology that simplifies and improves the safety of online login and authentication.
CardSpace是一个提供统一安全管理和身份认证的技术
通 过上面简单的介绍,发现在.Net Framework 3.0中一个关键的内容就是统一和集成,微软希望是在.Net Framework 3.0开发时代不需要让开发人员费尽脑筋考虑是选择WinForm还是Web,使用WebService还是Remotting、Com+等等的技术难 题,只需要按照.Net Framework 3.0的技术架构开发,就可以做到开发阶段的部署透明化(呵呵!多么美好的未来呀!!!)。
Windows Workflow Foundation是帮助您在Windows平台上快速建立工作流应用程序的编程模型、引擎和工具,为开发和执行各种基于工作流的应用程序提供了编程框架和工具。
Windows Workflow Foundation 对执行模型进行了活动自动控制方面的虚拟化。这使您能编写可以捕捉各种控制流模式的复合活动,范围包括多种连接和合并、状态机、图形、序列、交叉存取和非本地退出等。总之,它将使您能够通过“高保真”的复合活动对存在于现实世界中的控制流模式进行建模。
Windows Workflow Foundation是一个帮助你开发基于Windows平台的工作流解决方案的可扩展的框架。作为将来Microsoft WinFX的一部分,Windows Workflow Foundation提供一组API和工具以支持基于工作流的应用程序的开发和执行。Windows Workflow Foundation为创建跨越不同应用程序的端到端解决方法提供了一个简单、统一的模型。
Windows Workflow Foundation是一个通用的工作流框架。基于Windows Workflow Foundation的解决方案由相互链接的.NET组件构成并运行在宿主程序中。就像你在一个特定的设计环境下创建ASP.NET页面一样,Windows Workflow Foundatio也为你提供了一个良好的设计环境,在可视化设计器中,你可以创建特定的流程、在工作流组件中增加代码、定义商业过程,
Windows Workflow Foundation提供了工作流引擎、.NET-managed API、运行时服务、与Visual Studio 2005集成的可视化编辑器和调试工具。你可以使用Windows Workflow Foundation创建和执行运行在客户端和服务器端的工作流,并且可以运行在所有的.NET应用程序中。
.Net Framework 3.0开发环境
操作系统:
最低运行要求为 Windows XP Service Pack 2 (SP2) 或 Windows Server 2003。
开发工具和安装步骤,对仅做wwf,4、5可以不装:
1. .Net Framework 2.0(如果安装VS2005可以略过该步骤)
2. Visual studio 2005 (可以使用 Express Edition)
3. .NET Framework 3.0(WinFX) runtime components。(dotnetfx3setup.exe)
4. Windows SDK--1G左右 (6.0.6000.0.0.WindowsSDK_Vista_rtm.DVD.Rel.img)
5. vsextwfx.msi(是VS2005开发WPF、WCF的插件)
6. Visual Studio 2005 Extensions for Windows Workflow Foundation (EN).exe (是一个WF可视开发环境)
工作流需要与主机环境同步 — 通常是 Windows Forms 应用程序或 ASP.NET 应用程序。事件组中的活动能使工作流停止以等待外部事件、处理接收的事件,或只是在执行下一步之前进行等待。最后,Web 服务和状态组将目标锁定在工作流的两种特殊功能 — 将内部引擎为公开为 Web 服务或公开为状态机。
Sequential(顺序)模型
Sequential模型是流程按照事先预定的顺序执行,其中有可能存在分支(IFELSE)、循环(WHILE)等流程。
State Machine(状态机)模型
State Machine模型是以事件(Event)为驱动,使得流程本身转换不同的状态,每个状态有其转变的范围(即都可以转变成那些状态)和驱动事件。
我们还是以一个图来介绍WF的一些关键概念和WF的组成部分。WF包括了Runtime Services(运行时服务)、Runtime Engine(运行时引擎)、Base Activity Library(基础Activity库)。基于此我们要理解如下概念:
l Workflows are a set of Activities
Workflows是一个Activity的集合
l Workflows run within a Host Process: any application or server
Workflows需要寄宿在一个进程中,任何的应用或者服务都可以是Workflow的宿主
l Developers can build their own Custom Activity Libraries
开发人员可以构建自己的Activity类库
l Base Activity Library
Out-of-box activities and base for custom activities
基础的Activity类库,是自定义Activity的基类
l Runtime Engine
Workflow execution and state management
负责Workflow的执行和管理的引擎
l Runtime Services
Hosting flexibility and communication
负责Workflow寄宿和通讯的服务
l Visual Designer
Graphical and code-based construction
一个图形化的设计器
通过这些概念我们了解到一个Workflow是由多个Activity组成,这些Activity可以WF中预定义的基础Activity也可以是用户自定义的Activity;Workflow需要有自己的Runtime,这个Runtime负责了Workflow的执行、管理和通讯。
这里有一个非常重要的概念就是Activity。所有的Workflow都是由Activity组成,那么什么是Activity呢?接下来我会向大家介绍。
我们可以从两个方面理解Activity:
Activities are the building blocks of workflows
Activity是workflow一个已经编译的模块
l The unit of execution, re-use and composition
是一个可执行的、可重用和可以组合的单元
l Basic activities are steps within a workflow
基础的Activity是Workflow的一个步骤
l Composite activities contains other activities EG: Sequence
复杂的Activity可以包含其他的Activity,例如:Sequence(一个WF预定义的Activity)
l Partners and customers author custom activities EG: “ApproveOrder”
Activity可以是合作伙伴或者客户提供的一个自定义的Activity,这个Activity可能完成一些特定的商业逻辑,例如:“ApproveOrder”
Activities are classes:
l Properties and events are defined by the activity author and programmable from workflows
可以在Activity中定义属性和事件由workflow使用
l Has methods that are coded by the activity author but invoked by the workflow runtime (EG: Execute) or designer
Activity中的方法是由Activity的作者实现(如:Execute),由workflow或则设计器进行调用
l Can be built into workflow assemblies or deployed as re-usable libraries
可以编译在workflow中或则作为可重用库依赖于workflow
下面代码演示了一个Activity的例子:
public partial class SendEmailActivity :
System.Workflow.ComponentModel.Activity
{
public SendEmailActivity()
{
............
}
// override Execute with your custom logic
protected override ActivityExecutionStatus
Execute(ActivityExecutionContext context)
{
// you custom logic
return ActivityExecutionStatus.Closed;
}
//property
public string To
{
get{........;}
set{........;}
}
//event
public event EventHandler<CustomActivityEventArgs> Sending
{
add{........}
remove{........}
}
}
这里面一直在重点强调Activity的是重用,可以说一个Activity的最重要之处就是重用。重用不单单是代码的重用,而是业务逻辑的重用,这也是工作流应用的灵活之处。在开发工作流应用的时候,怎样划分业务逻辑?业务逻辑的颗粒度有多细?WF并没有规定,况且这个问题是仁者见仁,智者见智,并没有一个统一的定论。
个人的理解在定义一个Activity时要做到第一可重用、第二松耦合。在本文中只是对WF的组成和工作原理进行简单的介绍,不会深入讨论业务逻辑的划分和定义,我想即使不使用WF,业务系统也会遇到同样的问题。
在自定义Activity时还有几个比较重要的概念,分别是Designer、ActivityValidator、CodeGenerator、Serializer、ToolboxItem和定义行为的SupportsTransaction、SupportsExceptionHandlers。实际上这些该是Activity的Attribute类,分别制定了Activity在设计器中的UI界面、对Activity在设计期间的完整性校验、Activity的序列化等操作。具体内容我会在后面章节具体介绍,这里只介绍如何使用。
[Designer(typeof(CustomActivityDesinger),typeof(IDesigner))]
[ActivityValidator(typeof(SendEmailValidator))]
public partial class SendEmailActivity :
System.Workflow.ComponentModel.Activity
{
......
}
public class CustomActivityDesinger : ActivityDesigner
{
......
}
public class SendEmailValidator :
System.Workflow.ComponentModel.Compiler.ActivityValidator
{
......
}
1:Control Flow Activity:控制流程类
l Sequence Activity:顺序流程,使您能够协调一组子活动的连续执行。该序列在最后一个子活动完成之后完成。
l Parallel Activity:并行流程,使您的工作流能够相互独立地执行两个或更多个操作。该活动在继续执行之前会等待这些操作终止。
l IfElse Activity:条件判断流程,使您的工作流能够有条件地执行多个可供选择的分支之一。可在每个分支上放置一个条件,而条件为真的第一个分支将执行。无需在最后一个分支上放置条件,因为它被视为“else”分支。
l While Activity:循环流程,使您的工作流能够在一个条件被满足时执行一个或多个活动。在每次迭代之前,都评估该条件。如果为真,则所有子活动都会执行;否则,该活动完成。可指定声明性条件或代码条件。
l ConditionedActivityGroup:条件组,使您的工作流能够基于特定于每个活动的准则有条件地执行一组子活动,直到针对 CAG 整体满足完成条件。子活动相互独立并可能并行执行。
l Replicator Activity:自我复制。可以在运行中自我复制实例。使您的工作流能够创建给定活动的任意多个实例,并且顺序或同时执行它们。
l Delay Activity:延时执行,使您能够控制工作流的定时以及将延迟内置到工作流。您可以在Delay 活动上提供超时,以便工作流在恢复执行之前暂停。
l InvokeMethod:使您的工作流能够调用接口上的方法,以便将消息从工作流发送到向WorkflowRuntime 注册的数据交换服务。
l Policy:使您能够表示或执行规则集合。该活动不在工具箱中;要访问它的功能,必须创建自定义活动并使用派生。
2:Workflow Lifetime Activity:工作流相关
l InvokeWorkflow Activity:调用执行另外的工作流,使您的工作流能够调用或启动另一个工作流(可达到任意深度)。例如,被调用的工作流可以调用第三个工作流,该工作流又可以调用第四个工作流,等等。递归调用不受支持。受支持的调用模型是发后不理。
l Suspend Activity:暂停当前执行的工作流。挂起工作流的操作,以便能够在发生某个错误条件时进行干预。当工作流实例挂起时,将记录错误。可指定一个消息字符串来帮助管理员诊断发生了什么事情。与当前实例关联的所有状态信息都被保存,并且这些信息会在管理员继续执行时恢复。
l Terminate Activity:中止工作流。使您能够在发生任何异常情况时立即结束工作流的操作。如果是在 Parallel 活动内部调用,则所有分支都被突然终止,而无论它们的当前状态如何。当工作流终止时,会记录错误,并提供一个消息以帮助管理员弄清楚发生了什么事情。
3:Event Waiting Activity:事件类
l EventSink:在向 WorkflowRuntime 注册的数据交换服务引发指定事件时,使工作流能够从该服务接收数据。
l EventDriven Activity:等待事件驱动。指定要等待处理的事件名,参数等。代表一系列其执行由事件触发的活动。第一个子活动必须能够等待外部事件。可行的首要子活动是 EventSink 和Delay。在这种情况下,Delay 用作超时。
l Listen Activity:侦听消息。这个可以同时侦听很多消息。一个Listin里面有多个EventDriven。使工作流能够等待(可能存在的)多个事件之一,或者在指定的超时间隔之后停止等待,并且基于结果分支。可向每个分支中添加一个或多个由事件驱动的活动。只有第一个满足条件的分支被执行;其他分支都不会运行。
4:Transaction and Exception Activity:事务和异常处理类
l Transaction Context Activity:处理事务中的上下文,支持短期、长期的事务。事务上下文是用于对活动进行分组的块。该活动主要用于事务性执行、补偿和异常处理,可以根据情况进行同步。通过同步事务性上下文,可确保对活动*享数据的任何访问都将正确地序列化。
l Throw Activity:抛出异常。使您能够引发指定类型的异常。使用该活动等效于在用户代码中引发异常的代码处理程序。该活动是引发 .NET 异常的声明性方式。
l ExceptionHandler:异常处理。使您能够处理指定类型的异常。ExceptionHandler 活动是其他活动的包装,在指定的异常发生时,这些活动实际执行所需的任何工作。可根据情况指定一个用于存储异常的本地变量,并且使其可以在代码隐藏中使用。
l Compensate Activity:补偿处理,只能放在Exception中,处理一些回滚处理等。使您能够在发生错误时调用代码来撤消或者补偿已经由工作流执行的操作。通常,对于现在已被取消的操作,您可能希望向先前已经获得成功通知的用户发送电子邮件。
5:Data-Centic Activity:数据(交换)处理类:用于WF处理空间和Host空间之间的数据交换。
l UpdateData Activity:WF把数据更新到Host。使您的工作流能够通过在外部数据源对象上定义的方法更新数据存储区。当 UpdateData 活动被触发时,关联的方法将在宿主线程内部执行。
l SelectData Activity:WF发向Host的请求,使您的工作流能够通过在外部数据源对象上定义的方法查询外部数据。当触发 SelectData 活动时,关联的方法将在宿主线程内部执行。该方法返回的值被传递给工作流。
l WaitForData Activity:使您的工作流能够从外部数据源对象接收信息。当传入的数据修改绑定数据源的状态时,该活动被触发。传入的数据是通过绑定数据源服务接收的。
l WaitForQuery Activity:Host发向WF,WF返回DataSource。使外部应用程序能够在您的工作流中查询数据。该活动将在从宿主收到查询之前一直等待。来自外部应用程序的查询使用绑定数据源服务上的方法提交给工作流。
6:WebService Activity:WeSerivice的处理
l InvokeWebService Activity:调用WebService
使您的工作流能够调用 Web 服务方法。您需要指定要使用的代理类(使用 WSDL),以及您想要调用的方法的名称。同步和异步调用都受到支持。
l WebServiceReceive Activity:使作为 Web 服务本身公开的工作流能够接收 Web 服务请求。
l WebServiceResponse Activity:使作为 Web 服务本身公开的工作流能够响应 Web 服务请求。
7:The Code Activity:代码处理类
l Code Activity:可写一些代码,您能够向工作流中添加 Microsoft Visual Basic .NET 或 C# 代码以执行自定义操作。但是,这些代码不应该用对 Web 服务等外部资源的依赖性来阻塞工作流。但是我不觉得这样的处理好,因为这样的逻辑有点写死进程序里了。
8:State Workflow Activity:状态机工作流处理类
l State:表示状态机工作流中的状态。一个工作流必须有个初始状态,有个结束状态。
l StateInitialization:初始状态。我好像没用过这个。在 State 活动中,用作在状态转换时执行的子活动的容器。
l SetState:设置下一个状态。使您的状态机工作流能够指定向新状态的转换。
9:Custom Activity:用户自定义状态。
Visual Studio 2005 中的工作流项目类型
l 顺序工作流控制台应用程序 (Sequential Workflow Console Application):创建用于生成工作流的项目,该工作流包含一个默认的顺序工作流和一个控制台测试宿主应用程序。
l 顺序工作流库 (Sequential Workflow Library):创建用于以库的形式生成顺序工作流的项目。
l 工作流活动库 (Workflow Activity Library):创建一个用来创建活动的库的项目,以后可以将其作为工作流应用程序中的构造块重用。
l 状态机控制台应用程序 (State Machine Console Application):创建用于生成状态机工作流和控制台宿主应用程序的项目。
l 状态机工作流库 (State Machine Workflow Library):创建用于以库的形式生成状态机工作流的项目。
这个例子我们完成一个最基础的工作流,在控制台上显示一些此工作流自身的信息。
这个练习我们学习工作流相关的基本操作。
新建项目,选择“顺序工作流控制台应用程序”:
从工具箱中拖一个 到设计器:
填写代码:
选择codeActivity1,点属性页,ExecuteCode属性输入方法名称showInfo,双击方法名,Visual studio自动生成方法代码框架,
填写代码:
public sealed partial class Workflow1: SequentialWorkflowActivity
{
……
private void showInfo(object sender, EventArgs e)
{
CodeActivity c = (CodeActivity)sender;
Console.WriteLine("Hello, from ‘{0}‘./nI‘m an instance of the {1} class.",
c.Name, c.ToString());
Console.ReadLine();
}
}
运行可以看到:
这个例子我们实现一个工作流,弹出消息框,显示从主程序接收到的数据。
这个练习我们学习如何通过参数传递数据到工作流。
让 我们继续分析并修改该工作流,以使其在实例化以后接收和使用数据。有两种在实例化工作流以后使其接收数据的常规方法:参数和事件。如果选择使用参数,则需 要在可视化设计器中手动定义参数名称和类型的列表。如果选择使用事件,则需要创建并添加一个自定义活动(该活动充当在工作流模型中的某个位置介入的外部 源),并且传入一些数据。首先我们学习参数的使用,后面我们将说明基于事件的方法。
首先为Workflow1添加属性FirstName和LastName:
public sealed partial class Workflow1: SequentialWorkflowActivity
{
……
private string _FirstName;
public string FirstName
{
get { return _FirstName; }
set { _FirstName = value; }
}
//{
// 数据可以保存到UserData中,如下:
// get { return (string)UserData["FirstName"];}
// set { UserData["FirstName"] = value; }
//}
private string _LastName;
public string LastName
{
get { return _LastName; }
set { _LastName = value; }
}
……
}
在解决方案中新建一个windows 应用程序WinFormHost,设计主窗体如下:
添加引用:
生成tbStartWorkflow_Click事件并填写代码(代码可以从WorkflowConsoleApplication的program.cs中复制得到):
using System.Windows.Forms;
using System.Threading;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;
namespace WinFormHost
{
public partial class Form1 : Form
{
……
private void tbStartWorkflow_Click(object sender, EventArgs e)
{
using<