WF提供的标准活动中有很多复合活动,这些复合活动可以添加子活动比如:SequenceActivity,ParallelActivity,ReplicatorActivity等。这些活动都有特定的用途,如果WF提供的标准活动都不满足我们的需要的时候,我们就要自己开发一个复合活动。
活动的状态模型
活动在他的生命周期中有六种状态。 这些状态分别为 Initialized、Executing、Canceling、Closed、Compensating 和 Faulting。下图摘自MSDN中说明活动之间状态的转换关系:
1.红色实线表示工作流运行时引擎负责将活动从 Initialized 状态转换到 Executing 状态,或从 Closed 状态转换到 Compensating 状态。
2.黄色实线表示父活动负责将子活动从 Executing 状态转换到 Closed 状态。 如果您创建自定义复合活动,则必须亲自进行处理。
3.蓝色实线表示工作流运行时引擎负责将活动从 Executing、Canceling 或 Compensating 状态转换到 Faulting 状态。
4.黄色虚线表示工作流运行时引擎负责将活动从 Canceling 状态、Compensating 状态或 Faulting 状态转换到 Closed 状态。
5.仅当所有子活动都处于 Closed 或 Initialized 状态时,才能关闭活动。
活动执行上下文(AEC)
AEC是在宿主应用程序调用 Start 方法时为活动创建的执行环境。AEC可以使用ExecuteActivity 或CancelActivity方法来执行或取消 子活动。 也可以通过 CloseActivity方法 方法来关闭自己。 这些是仅有的父活动可以通过 AEC 控制的执行状态更改。 所有其他活动状态都是由工作流运行时引擎控制的。
关于活动状态和AEC的在《WF本质论》的前几章中有非常详细的讲解,推荐大家去看看。
开发一个自己的SequenceActivity
WF中所有的复合活动都继承子CompositeActivity,要开发一个基本的复合活动一般有以下几个步骤:
1.重写基类的Execute方法,在该方法中安排第一个子活动的执行,如果没有子活动要执行就返回Closed状态。还需要注册状态更改事件。
2.处理状态更改事件,在此我们判断是否还有子活动要执行,如果有就继续执行,如果没有就调用AEC的CloseActivity来关闭活动。
3.重写基类的Cancel方法,处理如当有异常发生的时候来执行的取消逻辑。
下面我们就开发一个自己的SequenceActivity,我们建立一个顺序型工作流项目,新建一个自定义活动,代码如下:[Designer(typeof(SequentialActivityDesigner))]
public partial classCarySequenceActivity: CompositeActivity,
IActivityEventListener<ActivityExecutionStatusChangedEventArgs>
{...}
该活动继承自CompositeActivity活动和接口IActivityEventListener<ActivityExecutionStatusChangedEventArgs>,IActivityEventListener接口用于监听活动的执行状态事件的更改的相关信息。
1.我们首先重写基类的Execute方法,代码如下:
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext) { if (this.EnabledActivities.Count == 0) { return ActivityExecutionStatus.Closed; } else { this.EnabledActivities[0].RegisterForStatusChange(Activity.ClosedEvent, this); executionContext.ExecuteActivity(this.EnabledActivities[0]); } return ActivityExecutionStatus.Executing; }
2.实现IActivityEventListener接口的OnEvent方法,代码如下:
public void OnEvent(object sender,ActivityExecutionStatusChangedEventArgs e) { ActivityExecutionContext context = sender as ActivityExecutionContext; if (context == null) { throw new ArgumentException("Expected sender to be an ActivityExecutionContext","sender"); } e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, this); Int32 activityIndex = this.EnabledActivities.IndexOf(e.Activity); if (activityIndex == this.EnabledActivities.Count - 1) { context.CloseActivity(); } else { activityIndex++; if (this.ExecutionStatus == ActivityExecutionStatus.Executing) { this.EnabledActivities[activityIndex].RegisterForStatusChange(Activity.ClosedEvent, this); context.ExecuteActivity(this.EnabledActivities[activityIndex]); } else if (this.ExecutionStatus == ActivityExecutionStatus.Canceling) { if (CancelProcessing(context)) { context.CloseActivity(); } } } }
3.重写基类的Cancel方法,代码如下:
protected override ActivityExecutionStatus Cancel(ActivityExecutionContext executionContext) { if (CancelProcessing(executionContext)) { return ActivityExecutionStatus.Closed; } else { return ActivityExecutionStatus.Canceling; } } private Boolean CancelProcessing(ActivityExecutionContext executionContext) { Boolean isTimeToClose = true; foreach (Activity activity in this.EnabledActivities) { if (!isTimeToClose) { break; } switch (activity.ExecutionStatus) { case ActivityExecutionStatus.Executing: executionContext.CancelActivity(activity); isTimeToClose = false; break; case ActivityExecutionStatus.Canceling: case ActivityExecutionStatus.Compensating: case ActivityExecutionStatus.Faulting: isTimeToClose = false; break; case ActivityExecutionStatus.Initialized: case ActivityExecutionStatus.Closed: break; default: break; } } return isTimeToClose;
}
4.这样我们就完成一个基本的复合活动,该活动的功能和WF提供的标准活动SequenceActivity相似,如果你现在使用
Reflector反编译一下WF本身提供的SequenceActivity活动的源代码,你会发现我们的处理方式是几乎相同的。我们
就来测试一下该活动,生成项目后,我们在工作流设计器上拖入CarySequenceActivity活动,向该活动内放几个
CodeActivity活动,如下图:
5.运行工作流,我们可以看出几个CodeActivity都正常执行了,如下图:
你也可以测试当该活动的子活动正在执行的时候,工作流发生了异常,此时就会执行该活动的取消逻辑。在此我们就不再测试了。
发表评论
-
平淡的2007
2007-12-24 08:04 817早上起来,送女朋友去公交车站,然后回来赶紧打开电脑,先 ... -
DreamSpark发布,高校学生免费使用Visual Studio 2008 Professional Edition 等微软软件
2008-02-20 13:23 1416今天上网无意中搜索到学生可以免费使用VS2008专业版,后来又 ... -
坚持学习WF(1):从HelloWorld开始
2008-04-04 16:30 892[置顶]坚持学习WF文章索 ... -
坚持学习WF(2):WF创作模式和设计时工具
2008-04-05 17:19 639[置顶]坚持学习WF文章索 ... -
坚持学习WF(3):WF框架概览
2008-04-08 07:27 783[置顶]坚持学习WF文章索 ... -
坚持学习WF(4):活动(Activity)和依赖属性(DependencyProperty)
2008-04-12 00:01 1148[置顶]坚持学习WF文章索引 活动(Activity) 活动 ... -
坚持学习WF(5):自定义活动(CustomActivity)
2008-04-13 15:25 929当WF提供的标准活动不能满足我们的需求的时候,我们就需要定义自 ... -
MOSS点滴(1):如何开发和部署feature
2008-04-16 21:35 836Features 是MOSS 2007以开箱即用的一套新功能, ... -
MOSS点滴(2):自定义Application Page
2008-04-19 20:07 845在MOSS中后台管理的页面都是Application Pag ... -
坚持学习WF(6):开发可复用的宿主程序
2008-04-21 21:45 696我们之前写工作流宿主 ... -
MOSS点滴(3):说说MOSS中的母版页
2008-04-25 21:15 1189MOSS中有两种页面:Site P ... -
MOSS点滴(4):实现Form认证
2008-04-29 21:12 705本文主要参考了网上的一些文章,但有些文章有些地方说的不是很明确 ... -
坚持学习WF(7):流程控制(Flow Control)
2008-04-30 18:10 839本文主要说说WF中和流 ... -
坚持学习WF(8):本地服务之调用外部方法
2008-05-09 08:17 761WF提供了一组核心服务 ... -
MOSS中的WebPart开发
2008-05-10 13:53 1060由于在asp.net1.1的时候asp.net中还没有webp ... -
坚持学习WF(9):本地服务之事件处理
2008-05-28 07:49 800[置顶]坚持学习WF文章索引 一:先来介绍两个活动 Even ... -
坚持学习WF(10):在工作流中使用关联
2008-06-01 13:03 692[置顶]坚持学习WF文章索 ... -
坚持学习WF(11):工作流通信与队列
2008-06-07 15:45 736[置顶]坚持学习WF文章索引 WF 提供的通信模型是构建于 ... -
MOSS中创建自定义内容类型
2008-06-12 20:23 1107一:简要介绍 某类内容 ... -
.NET中IDisposable接口的基本使用
2008-06-15 12:01 950首先来看MSDN中关于这个接口的说明: [ComVisible ...
相关推荐
复合蔬菜汁是一种将多种蔬菜通过特定工艺混合而成的饮品,旨在提供更为丰富的营养成分和更佳的口感。本文主要分析了胡萝卜、冬瓜、番茄三种蔬菜复合汁的基本成分,以探讨其营养价值,并与单一蔬菜汁进行比较。 1.1 ...
此外,“成骨细胞”在骨骼形成和维护过程中扮演着关键角色,其增殖和分化是骨骼修复过程中的基本生理活动。通过了解这些关键成分和过程,我们可以更好地掌握材料如何在体内发挥作用,从而设计出更符合生物需求的材料...
基于职位的人力资源管理系统的特点是以职位为核心,通过职务分析来确定岗位的目的、岗位工作关系、岗位主要职责活动、岗位权限、任职者的基本能力要求等岗位因素,形成岗位描述和岗位规范,并在此基础上建立人力资源...
作为一种环保型纤维,lyocell不仅对环境友好,还具有良好的吸湿性和穿着舒适性,能够满足人们对日常服饰的基本需求。 其次,抗紫外面料层的设计理念则是在提高面料透气性和吸湿速干性能的同时,增强其抗起毛起球的...
在此背景下,石墨烯复合抗菌防护服的创新之处体现在多个层面。首先是设计创新,该防护服采用连帽一体式结构,配合弹力带的设计,有效增加了活动的余量,显著降低了在动作剧烈时防护服被撕裂的风险。其次,从材料选用...
组织文化强调尊重、互利和优质学习,旨在建立一个高效协作的研发团队。通过协助核心厂商,提升现有产品的竞争力,同时瞄准国内第一,甚至世界一流水平。研发与合作模式涵盖了从产品开发到市场应用的全过程,强调技术...
2. 复合处理:将魔术贴与弹性材料如氨纶等进行复合,增强其延展性和适应性,以适应婴儿活动时的身体变化。 3. 切割与成型:根据纸尿裤尺寸精准切割魔术贴,并确保边缘平滑,防止勾丝。 4. 质量检测:通过严格的质量...
1. 定义活动(Activity):活动是工作流的基本构建块,代表了工作流程中的一个可执行单元。开发者可以通过继承`System.Activities.Activity`基类来自定义活动。 2. 工作流定义语言(XAML):WF支持使用XAML来可视化...
- **活动状态**:代表活动的执行状态,当一个活动完成时,控制流会转移到下一个或多个活动状态。 - **对象**:活动的输入或输出对象,是活动执行的前提条件和结果。 - **变迁**:描述活动状态之间的转换,同时也表示...
例如,`WriteLine`就是一个简单的活动,而复合活动可以包含多个子活动。 在创建自定义活动时,通常会从`CodeActivity`或`NativeActivity`等基类派生。例如,如果要创建一个简单的`WriteLine`活动,可以从`...
【年加工100万支复合绝缘子项目环境影响报告表】是企业在实施涉及环境因素的建设项目时必须完成的一项重要文档。这份报告旨在评估新建或扩建项目可能对周围环境产生的影响,确保符合国家环境保护法规和政策。以下是...
《统一建模语言参考手册-基本概念》是学习和理解UML(Unified Modeling Language)的基础资源,由Adams Wang翻译成中文,对于在中国的软件开发者和系统分析师来说,这是一个宝贵的工具,可以帮助他们更好地掌握这一...
商业地产开发技术和盈利模式是房地产行业中一个重要的领域,它涉及到如何有效地设计、建造、运营和管理商业物业以实现最大的经济效益。姜新国先生是中国商业地产领域的权威,他的专业知识和实践经验为这一领域提供了...
1. abort - 中止:指停止一个程序或进程的执行。 2. abstract class - 抽象类:不能直接实例化的类,通常包含抽象方法。 3. accelerator - 快捷键:通过按键组合快速执行命令的机制。 4. accelerator mapping - ...
文档中的内容是沈阳经济技术开发区内的一些企业名录,涵盖了企业的名称、经营地址、法定代表人...对于投资者、供应商或寻求就业的人来说,这份文档提供了一个初步的参考指南,可以帮助他们更好地定位目标企业和行业。
产品构成的核心在于它不仅仅是一个单一的物品,而是一个包含多个层次的复合概念。在产品构成的五个层次中,核心产品是企业应该首先明确的,它代表着产品的本质功能和消费者的基本需求。以手机为例,其核心产品是实现...
首先,我们要明白,虽然Java可能不是构造商业级游戏的最佳选择,因为它的运行效率相比C++等语言较低,但在学习编程技巧和理解基本概念方面,Java是一个非常有用的工具。 文章首先提到了一个简单的小游戏作为示例,...
4. ** 页面(Pages)和复合视图(Composite Views)**:如何组合多个视图形成一个复杂的用户界面。 ### 第六章:界面开发工具 这一章主要关注提高开发效率的工具和技巧: 1. ** 视图模板(View Templates)**:...