代码改变世界

《WF编程》系列之15 - 顺序工作流与SequenceActivity

2007-04-26 10:54  Windie Chai  阅读(5733)  评论(6编辑  收藏

3 顺序工作流

Windows Worklow提供两种现成可用的工作流执行风格:顺序和事件驱动(event-driven).顺序工作流的执行过程是一个连续的步骤序列,它在完成一个活动之后会去执行到下一个.比如用顺序工作流模拟将访问记录从网站日志转移到数据库中的操作:第一步,下载日志文件;第二步,将日志批量插入数据库中;第三步,创建新记录的统计结果.尽管顺序工作流也可以使用分支和循环,并且可以接收外部事件,但它的执行过程是可以预料的,并且总是向前执行直到完成为止.

事件驱动工作流则依赖外部事件来驱动执行直到完成.事件驱动工作流也叫做状态机(state machine)工作流.状态机中包含一系列状态(包括初始状态和结束状态)和事件.状态机总是停在一个预设的状态中,直到事件触发之后才会跳转到新的状态上.

3.1 SequenceActivity

活动是Windows Worklow的基本组成块,准确的说,顺序工作流本身就是一个活动-SequentialWorkflowActivity.SequentialWorkflowActivity类继承自SequenceActivity类, SequenceActivity类又继承自CompositeActivity类.这些超类规定了顺序工作流的行为和特征.如下面的类图:



继承自CompositeActivty类的活动可以包含一个或多个子活动.顺序工作流通常包含多个子活动(而且子活动也可以是CompositeActivity).

继承自SequenceActivity的活动总是向前遍历其子活动.SequenceActivity一旦执行完一个子就移动到下一个子活动.当最后一个子活动完成后,序列也就结束了.还有一点需要知道的是SequenceActivity并没有跳转到任意活动的机制.

3.1.1 简单的顺序工作流

作为示例,我们创建一个简单的顺序工作流.这个工作流的功能是增加计数器的计数并输出到屏幕上.首先新建一个Sequential Worklow Console Application项目.项目中包括一个应用程序和一个名为Workflow1的工作流定义.右键单击Workflow1并选择查看代码,在code-beside文件中添加以下代码:

public partial class Workflow1 : SequentialWorkflowActivity

{

int counter = 0;

}

接下来我们从工具箱中拖拽一个CodeActivity到设计器表面.顺序工作流和SequenceActivity的典型执行过程是从最顶端到最底端.拖拽活动时,拖拽点()会显示在指针附近的执行线上.在属性面板中,将这个CodeActivity命名为IncrementCounter.然后再拖拽一个CodeActivity到第一个活动的下方,命名为WriteCounter.最终效果如下图:


下一步,我们通过双击设计器中的活动来给IncrementCounter活动添加一个ExecuteCode事件.设计器会生成该事件的空方法,我们需要做的就是提供详细的内部实现.只需添加一行代码来增加计数:

private void IncrementCounter_ExecuteCode(object sender, EventArgs e)

{

counter
++;

}

然后返回设计视图,双击WriteCounter,添加下面的代码:

private void WriteCounter_ExecuteCode(object sender, EventArgs e)

{

Console.WriteLine(
"The value of counter is {0}.", counter);

}

这时运行这个工作流,我们可以看到一行输出,显示The value of counter is 1.顺序工作流依序执行了两个子活动,在它们执行完后,顺序工作流也就完成了.接下来,让我们添加一些控制流程的活动使工作流更加有趣.

3.1.1.1 序列中的序列

WhileActivity会重复执行它的子活动直到它的条件返回false为止.我们可以拖拽一个WhileActivity来作为工作流的第一个活动.一个空的WhileActivity将在设计器中会显示Drop An Activity Here.这说明我们只能在WhileActivity中添加一个子活动.WhileActivity继承自CompositeActivity类,这意味着它可以包含多个子活动,但是它没有继承SequenceActivity.所以WhileActivity只能执行一个子活动.如果想要在WhileActivity添加多个子活动的话,我们需要把这些活动置于一个SequenceActivity内部,然后把SequenceActivity拖拽到WhileActivity中.工作流最终效果如图所示:



在运行工作流之前,我们需要指定WhileActivity的条件.我们可以把条件写到一个外部规则文件中,也可以直接写到代码中.我们添加下面的方法到工作流代码中:

private void CheckCounter(object sender, ConditionalEventArgs e)

{

e.Result 
= false;

if (counter < 10)

{

e.Result 
= true;

}

}


CheckCounter方法是一种特殊的方法,被称作代码条件(Code Condition).在WF中,代码条件通过ConditionalEventArgs参数的Result属性返回true或者false值.在WhileActivity的属性面板中,我们设置Condition为Code Condition,然后在下拉菜单中选择CheckCounter.现在我们可以在控制台中输出10行计数器增加的结果.

当然,并不是所有的工作流都仅仅需要一个counter字段和控制台就足够了.我们经常需要和工作流进行数据往来,传递或取出数据.