毛毛的小窝 — 关注技术交流、让我们一起成长

导航

统计

WF学习系列之五:状态机工作流学习

1 简介

工作流实际上是对业务处理过程的建模,当我们设计工作流的时候,我们首先要分析业务处理过程中要经历的步骤。然后,我们就可以利用WF创建工作流模型来模拟业务的处理过程。

我们知道,WF包含两种类型的工作流:顺序工作流和状态机工作流。顺序工作流提供了一系列有组织的步骤,一般情况下,步骤是逐一执行的。可能有的步骤需要等待某些事件的发生才可以继续执行,但通常情况下顺序工作流一般用于无需人工干预的操作。

状态机工作流提供了一系列的状态。工作流从初始状态开始,到终止状态结束。两个状态之间定义行为进行过渡。通常情况下,状态机工作流对事件作出反应,事件的发生将会使状态发生改变。

至于到底采用哪种类型的工作流取决于具体的业务管理过程。例如,你要建立一个工作流来模拟订单的处理过程。具体步骤如下:

l         商店接受了订单,包括下单人、产品、数量等信息;

l         商店检查客户是否拥有合法的信用卡。如果有,继续,否则结束;

l         商店检查存货清单是否能够满足订单要求。如果有,继续,否则结束;

l         商店要求信用卡公司支付合同金额。如果成功,继续,否则结束;

l         将商品托运给客户。流程结束。

从以上过程来看,采用顺序工作流就可以一气呵成。

假如情况有如下变化:

l         商店接受了订单,包括下单人、产品、数量等信息;

l         商店检查客户是否拥有合法的信用卡。如果有,继续,否则结束;

l         商店检查存货清单是否能够满足订单要求。如果有,继续,否则结束;

l         如果产品有现货,产品货运公司托运产品;

l         在托运之前,商店要求信用卡公司支付产品费用。如果成功,继续,否则结束;

l         当产品托运后,处理流程等待客户确认已经收到。如果收到,流程结束。如果客户没有收到,流程将等待商品重新发送。在这时,商店和客户都可以取消订单,结束进程。

这个流程和前一个流程的区别在于:有些过程需要暂时中止并等待其他过程的开始。这个中止过程一般情况下需要几天时间(网上购物大概3-5天)。

状态机工作流的好处在于它可以定义状态,定义工作流如何从一个状态到另外一个状态。当外面的事件发生的时候,状态机工作流可以移动到不同的状态。外部行为可以是宿主程序引发工作流内部事件,也可以是宿主程序编程实现的下一个状态,也可以利用SetState Activity移动到下一个状态。

2 创建状态机工作流

具体参加原文,这里只介绍状态机工作流特有的几个活动:State activity, SetState activity, StateInitialization activity, StateFinalization activity

3 定义工作流状态

拖拽三个State activity,分别设置为开始、工作、结束三个状态。

4 状态过渡

利用SetState activity,通过TargetStateName属性进行设置。

5 在每个状态定义活动

我们可以将四种活动添加到State Activity中:

StateInitialization activity:只要它存在,则进入状态后,改活动第一个执行。StateInitialization activity是一个顺序化的活动,你可以将增加所有的活动,包括SetState activity

EventDriven activity:利用它可以控制外部事件,它也是一个顺序化的活动,可以将增加所有的活动,包括SetState activity

StateFinalization activity:离开状态最后执行的活动,它也是一个顺序化的活动,可以将增加所有的活动,包括SetState activity

State activityState activity可以再嵌入State activity以形式具有等级结构的状态机工作流。这样,子状态活动可以继承父状态活动的driven behavior event

6 通讯服务

对状态机工作流来说,典型的应用场景是工作流进入一个状态,然后等待宿主程序引发事件。通过EventDriven activity处理外部事件。你可以决定工作流执行的行为是什么,包括下一个要移动的状态。这里主要介绍两个活动:

HandleExternalEventActivity

l         挂起当前流程,当外部触发事件时,流程继续向下运行

l         引擎中要加载ExternalDataExchange服务

l         ExternalDataExchange服务,要加载实绑定接口的类实现

l         运行到HandleExternalEventActivity结点后,会进入idle状态,苏酲时间为9999-12-31

l         只有当宿主中触发绑定的事件后才会继续向下运行。

l         在实例挂起或没到HandleExternalEventActivity结点时,也可以在外部触发事件,这时当实例运行到该结点时HandleExternalEventActivity就可直接过去,而不用再触发了

 

CallExternalMethodActivity

l         在工作流内部调用外部方法

l         引擎中要加载ExternalDataExchange服务

l         ExternalDataExchange服务,要加载实绑定接口的类实现

l         运行到CallExternalMethodActivity结点后自动调用实例中的方法。用参数映射中的设定传参,得到返回值

 

两个活动的说明:

    [ExternalDataExchangeAttribute]

     public interface IOrderManagement

     {

        event EventHandler<OrderEventArgs> OrderShipped;

        event EventHandler<OrderEventArgs> OrderShippingCancel;

        event EventHandler<OrderEventArgs> OrderAcknowledged;

        event EventHandler<OrderEventArgs> OrderReShipping;

 

        bool InStock(string productID, int quantity);

}

无论哪个活动,都必须有一个具有外部数据交换属性的接口。我个人反对在工作流代码中调用和业务逻辑相关的代码。所有和业务相关或数据库相关的代码都应该写在IOrderManagement的实现类中。HandleExternalEventActivity用于外部对工作流状态的调用,使工作流继续运行。CallExternalMethodActivity用于调用外部代码,以实现访问业务关心的代码,如判断库存是否满足要求,然后通过返回值决定工作流的运行路径。

7 具体实现

这里,我定义了四个状态,通过名称很容易知道每个状态的含义。

 

在开始状态,定义了一个调用外部方法活动,以检查数据库中的库存是否满足订单的要求,返回值为bool型,然后执行ifElse活动,以转向不同的状态。

 

WaitingForShipping状态含有两个处理事件:一个是发送订单,一个是订单取消。下图是发送订单的状态图。

 

参考文献

本翻译没有按照原文,详细请查阅

http://social.msdn.microsoft.com/content/en-us/msft/netframework/wf/learn/Intro-StateMachineWorkflows

http://www.cnblogs.com/foundation/

posted on 2008-12-19 17:15  mjgforever  阅读(2219)  评论(0编辑  收藏