`

如何开发一个基本的复合活动

阅读更多

WF提供的标准活动中有很多复合活动,这些复合活动可以添加子活动比如:SequenceActivity,ParallelActivity,ReplicatorActivity等。这些活动都有特定的用途,如果WF提供的标准活动都不满足我们的需要的时候,我们就要自己开发一个复合活动。

活动的状态模型
活动在他的生命周期中有六种状态。 这些状态分别为 Initialized、Executing、Canceling、Closed、Compensating 和 Faulting。下图摘自MSDN中说明活动之间状态的转换关系:

AC

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活动,
如下图:
ComAc1 
5.运行工作流,我们可以看出几个CodeActivity都正常执行了,如下图:
ComAc2 
你也可以测试当该活动的子活动正在执行的时候,工作流发生了异常,此时就会执行该活动的取消逻辑。在此我们就不再测试了。
 

分享到:
评论

相关推荐

    Android高级编程--源代码

    由于现有的手机应用程序的开发是构建在各手机厂家的私有操作系统之上的,所以它限制了第三方应用程序的开发,而Android为我们提供了一个开放和通用的选择。因为没有了人为制造的障碍,所以Android开发人员可以自由地...

    Android高级编程 part1

     Android提供一个开放的开发环境,为针对移动设备编写创新应用程序带来了激动人心的新机遇。作为使用AndroidSDK构建这些应用程序的实用指南书籍,《Android高级编程》从始至终穿插了一系列示例项目,每个项目都引入...

    Android高级编程 part2

     Android提供一个开放的开发环境,为针对移动设备编写创新应用程序带来了激动人心的新机遇。作为使用AndroidSDK构建这些应用程序的实用指南书籍,《Android高级编程》从始至终穿插了一系列示例项目,每个项目都引入...

    突破程序员基本功的16课.part2

    16.1.3 开发活动和测试活动 16.1.4 常见的Bug管理工具 16.2 单元测试 16.2.1 单元测试概述 16.2.2 单元测试的逻辑覆盖 16.2.3 JUnit介绍 16.2.4 JUnit的用法 16.3 系统测试和自动化测试 16.3.1 系统测试...

    Android高级编程.pdf

    2.1.2 创建第一个Android活动 2.1.3 Android应用程序的类型 2.2 面向移动设备的开发 2.2.1 关于硬件设计的考虑事项 2.2.2 考虑用户环境 2.2.3 Android开发 2.3 To-Do List示例 2.4 Android开发工具 2.4.1 Android...

    《Android高级编程》

    3.6.4 为不同的语言和硬件创建资源 3.6.5 运行时配置更改 3.7 深入探讨Android活动 3.7.1 创建一个活动 3.7.2 活动生命周期 3.7.3 Android活动类 3.8 小结 第4章 创建用户界面 4.1 Android UI基本设计 4.2 View简介 ...

    智能手机操作系统编程Symbian及60系列

     3.3.3 一个活动对象的例子  3.4 客户/服务器  3.4.1 Symbian OS客户/服务器结构框架  3.4.2 一个例子  3.5 描述符  3.5.1 描述符简介和分类  3.5.2 描述符的操作和使用  3.6 小结 第4章 应用程序设计  4.1...

    美河提供.智能手机操作系统编程Symbian及60系列1

     3.3.3 一个活动对象的例子  3.4 客户/服务器  3.4.1 Symbian OS客户/服务器结构框架  3.4.2 一个例子  3.5 描述符  3.5.1 描述符简介和分类  3.5.2 描述符的操作和使用  3.6 小结 第4章 应用程序设计  4.1...

    软件工程-理论与实践(许家珆)习题答案

    B) 图形工具能够极好地概括描述一个系统的信息,比文字叙述能够更好地表达重 要的细节 C) 图形能够更加直观地描述目标系统,便于用户理解和交流,有利于开发者与用 户之间达成一致的需求 D) 图形比文字描述简单、...

    软件体系结构(张友生版)期末复习题

    10. 软件产品线:就是在一个公共的软件资源集合基础上建立起来的共享同一个特性集合的系统集合。11. 框架:是封装了特定应用族抽象设计的抽象类的集合,框架又是一个模板,关键的方法和其他细节在框架实例中实现。

    高职计算机信息管理专业《数据库技术》课程教学改革.doc

    1.2 课程培养目标 通过数据库技术课程的学习,具有设计、使用和维护一个一般数据库系统的基本能力, 能够根据具体的信息管理工作要求,设计出符合要求的数据库系统,并掌握一定的界面 开发能力。 1.3 课程教学内容 ...

    计算机游戏程序设计(“游戏”相关文档)共25张.pptx

    对游戏开发的某一个方面达到较高水准 Game design documents 该游戏的可执行文件,以及相应的安装和用户手册 游戏开发项目(2/4) 教学目标 基本了解和掌握游戏程序设计 开发流程 组织开发理念 游戏内容相关的知识...

    C#微软培训资料

    第三章 编写第一个应用程序 .20 3.1 Welcome 程序 .20 3.2 代 码 分 析 .20 3.3 运 行 程 序 .23 .4 添 加 注 释 .25 3.5 小 结 .27 第二部分 C#程序设计基础.28 第四章 数 据 类 型 .28 4.1 值 类 型...

    测试覆盖率

     武友文以自己在国际公司的实践经验,一再强调,软件测试是软件开发过程中的一个重要步骤,或者说测试应该贯穿在软件开发过程的每一个阶段。软件测试所起到的作用就是:能够确保在软件开发的过程中,随时发现问题,...

    电子图书系统初步设计方案.doc

    例如,我们可以在Windows XP中创建一个Excel电子表格,然后使用FlashPaper将其转换为SWF文件,再将这个 SWF文件传给一个Macintosh用户。 数字扫描:系统实现纸质图书高速扫描,批量汉字自动识别、著录项标引和数字化...

    Visual C++实践与提高-COM和COM+篇『PDF』

    6.3.1 创建一个进程内自动化组件工程 6.3.2 分析新建工程文件 6.3.3 添加COM对象类 6.3.4 为接口添加属性 6.3.5 为接口添加方法 6.3.6 创建并测试组件 6.4 探讨MFC实现COM的内幕 6.4.1 MFC COM对象的实现 6.4.2 MFC ...

    软件工程之专题十一: 系统工程知识

    一个系统的基本组成部件包括输入流、输出流和处理过程。数据流是用于记录系统中各种流的抽象表达形式。数据流贯穿在组织内的每个活动中,数据流是用以控制其他流的,而事务流则是被控制的对象。 数据流图是一种便于...

    计算机应用专业课程设置调研报告.doc

    而小型企业由于 人才数量不足,对招聘人才的业务要求较高,希望招聘到知识面宽、操作技能强、适应 职业变迁和产品开发能力的复合型人才。 七、师资建设 1、加强计算机应用专业及相关技术师资的配备,提高技术力量,...

Global site tag (gtag.js) - Google Analytics