工作流编程循序渐进(8:状态机工作流)
作者 朱先忠
一、状态机工作流简介
状态机工作流由一组状态组成。一个状态被指示为 初始状态。每个状态都可以接收一组特定事件。视事件而定,可以转换到另一个状态。状态机工作流 可以有最终状态。当转换到最终状态时,工作流将完成。
[一]状态机设计器视图
状态机设计器是一种自由形式的设计器,这意味着可以在设计图面上自由移动活动。
状态机设计器有两个视图: |
(1)“ 状态”视图 (2)“ 事件驱动”视图 |
状态视图显示状态活动和可包含在状态活动内的事件驱动的活动。在此视图中,从一个状态到另一个状态的转换是由直线表示的,这些直线从一个状态中的事件驱动活动延伸到另一个状态。
也可以通过自己绘制直线来创建一个状态活动到另一个状态活动的转换。若要绘制转换,请你选择事件驱动的活动,然后选择活动上的某个手柄并拖动该手柄。此操作将绘制直线。此直线随后将连接到目标状态,指示状态之间的转换。如下图所示: |
若要访问事件驱动的视图,请 双击事 件驱动的活动。出现的设计器与顺序工作流设计器很像。在设计器的顶部,导航栏显示直到所显示事件驱动活动为止的活动层次结构。可以通过单击显示的层次结构 中的任意元素导航回状态视图。如果已在状态视图中绘制了从一个状态到另一个状态的转换,并且正在显示该活动的事件驱动视图,则会为您将一个已设置状态活动 添加到事件驱动的活动。如果更改已设置状态活动的属性,它将反映到状态视图中。
[二]状态机工作流活动
下表描述了状态机工作流设计器中使用的关键活动。
工具箱名称 | 活动 | 说明 |
---|---|---|
State | | 表示状态机中的一个状态;可能包含其他 StateActivity 活动。有关更多信息,请参见(可能为英文网页)。 |
SetState | | 指定到新状态的转换。有关更多信息,请参见(可能为英文网页)。 |
StateInitialization | | 在进入某个状态时执行;可能包含其他活动。有关更多信息,请参见(可能为英文网页)。 |
StateFinalization | | 在离开 活动时执行包含的活动。有关更多信息,请参见(可能为英文网页)。 |
EventDriven | | 用于依赖于外部事件开始执行的状态。 EventDrivenActivity 活动必须具有实现 接口作为第一个子活动的活动。有关更多信息,请参见(可能为英文网页)。 |
状态机工作流中的主要组成部分是 活动。在状态机工作流中的不同位置捕获了事件时,将会进入不同的状态,以处理与这些事件关联的任务。在工作流的生存期内,工作流可能会离开和进入若干不同的状态。这些状态通过使用 活动互相连接。
将新的 StateActivity 拖到工作流设计图面上时,您可以添加 、、 或其他 StateActivity 活动作为子活动。
警告: |
---|
使用状态机工作流设计器来创建工作流时,推荐使用“文档大纲”视图窗口来监视所设计工作流的结构。“文档大纲”视图窗口中状态机工作流结构的视图反映了工作流标记文件中活动的逻辑布局。工作流活动显示在设计图面上的物理布局可能不会反映工作流标记文件中活动的逻辑布局。 若要打开 “文档大纲”窗口,方法有二:(1)在 “视图”菜单上指向 “其他窗口”,然后选择 “文档大纲”;(2)也可以右单击某个状态活动, 然后选择 “文档大纲”。 例如下面的图形,左边显示的是 “文档大纲”,右边是相应的状态工作流。 |
二、创建控制台状态工作流示例程序框架
请遵循如下步骤创建一个实现简单的请假流程的控制台状态工作流示例程序: 1. 启动VS2008,单击菜单”文件“|”新建“|”项目“,创建一个名字为 MyStateWF 的控制台状态工作流示例程序。三、设计状态机工作流
3. 从工具箱中依次拖动四个State活动到上面的工作流设计器中。四、设计状态机中各活动的参数及有关函数
本实例中,绝大部分的代码活动仅是通过控制台输入简单的提示文字。对于上面的 左边的 IfElseBranch活动,在对应的属性对话框中指定Condition为“代码条件”,输入条件方法名为LeaveCondition ,按下回车,创建如下代码:private void LeaveCondition(object sender, ConditionalEventArgs e) { System.Threading.Thread.Sleep(5000); string result = Console.ReadLine(); if (result == "0") { e.Result = false; } if (result == "1") { e.Result = true; } } |
private void codeActivity1_ExecuteCode(object sender, EventArgs e) { Console.WriteLine("这是初始状态,请假流程开始!\n"); System.Threading.Thread.Sleep(5000); Console.WriteLine("开始提交请假申请\n"); } private void codeActivity2_ExecuteCode(object sender, EventArgs e) { System.Threading.Thread.Sleep(5000); Console.WriteLine("收到请假申请,请批示:!\n"); Console.WriteLine("输入0:不同意请假。\n"); Console.WriteLine("输入1:同意请假。\n"); } private void codeActivity5_ExecuteCode(object sender, EventArgs e) { Console.WriteLine("请假申请结束!\n"); } private void codeActivity3_ExecuteCode(object sender, EventArgs e) { Console.WriteLine("允许请假!"); } private void codeActivity4_ExecuteCode(object sender, EventArgs e) { Console.WriteLine("不允许请假!"); } |