zoukankan      html  css  js  c++  java
  • (转载)Windows workflow foundation(二)——(创建状态机工作流)(上)

    状态机工作流是为事件驱动的工作场景设计的。一个状态机工作流包含两个或两个以上的状态,且任意时刻只有一个处于激活状态。在这一节中,我们将创建一个基于状态机的工作流,这个工作流将通过其内部不同的状态,来处理宿主程序提交的订单。初始状态为WaitForOrderState只要宿主程序提交了一个新订单,这个状态就会执行。当收到一个新订单后,进入OrderProcessing状态开始处理订单。最后一个状态就是OrderCompletedState。在这个过程中,不同的状态将会与宿主程序交互。

     

    创建一个状态机工作流

     

    一个状态机工作流可以继承从StateMachineWorkflow类,这个类中已经实现了状态机工作流的大部分功能。一旦你继承了这个类,你就可以开始在工作流中加入所需的状态,并使用SetState活动或事件驱动的活动如EventSink把这些状态连接起来。以下的代码就是我们的工作流类OrderProcessingWorkflow,这个类是接下来整个示例程序的基础。你可能已经注意到了,类中声明了两个变量。这两个变量是用来存贮当前订单信息的,这些信息将会在整个流程中用到。

    using System;
    using System.Workflow.ComponentModel;
    using System.Workflow.Runtime;
    using System.Workflow.Activities;
    using System.Workflow.Activities.Rules;
     
    namespace Microsoft.Samples.Workflow.Quickstarts.StateMachine
    {
        
    public partial class OrderProcessingWorkflow : StateMachineWorkflow
        
    {
            
    private string orderId;
            
    private string itemStatus;
            
            
    public OrderProcessingWorkflow()
            
    {
                InitializeComponent();
            }

            
    private void InitializeComponent()
            
    {
            }

        }

    }

     

    创建活动和参数绑定

     

    WWF中有两个类ActivityBindParameterBinding,是专门用来将活动中的变量,绑定到方法调用所需的参数上的。这个方法定义在一个接口中,接口的实现就是注册到工作流中的服务。在我们的程序中,我们将把当前订单的orderIdstatus的值传递进去。以下的代码示例了如何创建和联系工作流的私有变量和参数。这些参数将用来根据当前工作流的状态来更新宿主。在稍后创建状态活动时,我们将用到这些绑定对象。

     

    开始创建活动和参数绑定

     

    1.  定义一个私有变量

    类型

    名称

    ActivityBind

    orderIdActivityBind

    ParameterBinding

    orderIdParameterBinding

    ActivityBind

    itemStatusActivityBind

    ParameterBinding

    itemStatusParameterBinding

    2.  以下代码示例了如何创建ActivityBindParameterBinding,以及怎样和私有变量绑定。

    //
    // Binding variables
    //
    orderIdActivityBind = new ActivityBind();
    orderIdParameterBinding 
    = new ParameterBinding();
    itemStatusActivityBind 
    = new ActivityBind();
    itemStatusParameterBinding 
    = new ParameterBinding();
     
    orderIdActivityBind.ID 
    = "/Workflow";
    orderIdActivityBind.Path 
    = "orderId";
    orderIdParameterBinding.ParameterName 
    = "orderId";
    orderIdParameterBinding.SetBinding(System.Workflow.ComponentModel.ParameterBinding.ValueProperty,
        ((System.Workflow.ComponentModel.Bind)(orderIdActivityBind)));
     
    itemStatusActivityBind.ID 
    = "/Workflow";
    itemStatusActivityBind.Path 
    = "itemStatus";
    itemStatusParameterBinding.ParameterName 
    = "newStatus";
    itemStatusParameterBinding.SetBinding(System.Workflow.ComponentModel.ParameterBinding.ValueProperty,
    ((System.Workflow.ComponentModel.Bind)(itemStatusActivityBind)));

     

    构造WaitingForOrder状态

     

    这第一个状态监听来自宿主的事件,这个事件通知工作流一个新的订单已经被提交了,应该马上处理它。当你创建状态时,状态的第一个子活动必须是StateInitialization活动或实现了IEventActivity接口的活动。这里的WaitForOrderState采用了后者,因为这个状态是由宿主程序的事件激活的。

    EventSink活动是用来监听注册在WWF运行库中的服务的事件的,在我们的程序中,这个服务由宿主程序提供。我们在工作流中定义了IOrderingService接口,这个接口稍后将由宿主程序实现。

    using System;
    using System.Workflow.ComponentModel;
    using System.Workflow.Runtime.Messaging;
     
    namespace Microsoft.Samples.Workflow.Quickstarts.StateMachine
    {
        [Serializable]
        
    public class NewOrderEventArgs : WorkflowMessageEventArgs
        
    {
            
    private string item;
            
    private int quantity;
     
            
    public NewOrderEventArgs(Guid instanceId, string item, int quantity)
                : 
    base(instanceId)
            
    {
                
    this.item = item;
                
    this.quantity = quantity;
            }


            
    public string Item
            
    {
                
    get return item; }
                
    set { item = value; }
            }


            
    public int Quantity
            
    {
                
    get return quantity; }
                
    set { quantity = value; }
            }

        }

        
        [DataExchangeService]
        
    public interface IOrderingService
        
    {
            
    void ItemStatusUpdate( string orderId, string newStatus);
            
    event EventHandler<NewOrderEventArgs> NewOrder;
        }

    }

     

    一旦EventSink活动处理了触发事件后,一个状态消息需要通过IOrderingInterface发回宿主程序。工作流需要调用接口中的ItemStatusUpdate方法,并传递orderIdnewStatues参数。而调用接口方法的工作,就交给InvokeMethodActivity活动了。我们指定活动的InterfaceType参数为我们需要的服务接口,MethodName属性设为要调用的服务接口中的方法名称,然后在ParameterBindings中加入之前构造好的参数绑定,最后为活动的MethodInvoking事件指定一个事件处理程序,用来改变当前订单的状态。因为我们已经把orderIdnewStatus参数绑定到了私有变量orderIditemStatus上,所以为ItemStatusUpdate方法传递参数的过程是由WWF运行库自动完成的。

    更新完成之后,WaitingForOrderState状态已经准备好转移下一个状态——OrderOpenState(译者注:这里错了,应该是OrderPrecessingState)状态。SetState活动是专门负责状态转移的。把一个SetState活动加入到EventDriven的最后一环,当一切处理完后,SetState活动将执行,并立马跳转到指定的下一个状态。

     

    开始构造WaitForOrderState

     

    1.  定义5个私有变量

    类型

    名称

    EventSinkActivity

    newOrderEventSink

    InvokeMethodActivity

    updatestatusOrderReceived

    SetState

    setStateOrderProcessing

    EventDriven

    eventDriven1

    State

    WaitingForOrderState

    2.  用默认构造函数实例化以上变量

    以下代码演示了如何构造WaitForOrderState。先是EventSinkActivity来处理宿主事件,然后InvokeMethodActivity来改变当前订单状态,并更新宿主状态。最后,SetState活动将WaitForOrder状态转移到OrderPrecessing状态。把这三个活动就依次加入到EventDriven活动的子活动中。

    //
    // WaitingForOrder State
    //
    this.newOrderEventSink = new System.Workflow.Activities.EventSinkActivity();
    this.newOrderEventSink.EventName = "NewOrder";
    this.newOrderEventSink.ID = "newOrderEventSink";
    this.newOrderEventSink.InterfaceType = typeof(Microsoft.Samples.Workflow.Quickstarts.StateMachine.IOrderingService);
    this.newOrderEventSink.Roles = null;
     
    this.updatestatusOrderReceived = new System.Workflow.Activities.InvokeMethodActivity();
    this.updatestatusOrderReceived.ID = "updatestatusOrderReceived";
    this.updatestatusOrderReceived.InterfaceType = typeof(Microsoft.Samples.Workflow.Quickstarts.StateMachine.IOrderingService);
    this.updatestatusOrderReceived.MethodName = "ItemStatusUpdate";
    this.updatestatusOrderReceived.ParameterBindings.Add(orderIdParameterBinding);
    this.updatestatusOrderReceived.ParameterBindings.Add(itemStatusParameterBinding);
    this.updatestatusOrderReceived.MethodInvoking += new System.EventHandler(this.OrderReceived);
     
    this.setStateOrderProcessing = new System.Workflow.Activities.SetState();
    this.setStateOrderProcessing.ID = "setStateOrderProcessing";
    this.setStateOrderProcessing.TargetState = "OrderProcessingState";
     
    this.eventDriven1 = new System.Workflow.Activities.EventDriven();
    this.eventDriven1.Activities.Add(this.newOrderEventSink);
    this.eventDriven1.Activities.Add(this.updatestatusOrderReceived);
    this.eventDriven1.Activities.Add(this.setStateOrderProcessing);
    this.eventDriven1.ID = "eventDriven1";
     
    this.WaitingForOrderState = new System.Workflow.Activities.State();
    this.WaitingForOrderState.Activities.Add(this.eventDriven1);
    this.WaitingForOrderState.ID = "WaitingForOrderState";

     

    你可以在InvokeMethodActivity活动执行的前一刻,加入一些附加的逻辑。只要为MethodInvoking事件指定一个处理程序,就能做到这一点。以下的代码就是MethodInvoking事件的处理程序。它为itemStatusorderId变量指定了新的值。事件处理程序的指定,已经在上面的代码中做了。

    private void OrderReceived(object sender, EventArgs e)
    {
        itemStatus 
    = "Received order";
        orderId 
    = Guid.NewGuid().ToString();
    }
  • 相关阅读:
    HDU 3336 Count the string(KMP+DP)
    PHP 错误与异常 笔记与总结(13 )自定义异常类
    数据分析中,你认为用户行为分析最重要的点是什么
    数据分析中,你认为用户行为分析最重要的点是什么
    如何进行大数据分析及处理_数据分析师
    如何进行大数据分析及处理_数据分析师
    大数据与传统数据的区别_数据分析师
    大数据与传统数据的区别_数据分析师
    数据分析师 之量化用户研究
    数据分析师 之量化用户研究
  • 原文地址:https://www.cnblogs.com/ghd258/p/309163.html
Copyright © 2011-2022 走看看