zoukankan      html  css  js  c++  java
  • WF Workflow 状态机工作流 开发

    概述

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

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

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

    在线诊断的业务流程图

    image

        

    现在来看WF 状态设计图

    image

    new workflow的序例图如下

    1

    WF workflow 传值方式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public sealed partial class CTDiagnosis : StateMachineWorkflowActivity
    {
        private WorkFlowActivityEntity internalMyActivityData;
     
        public WorkFlowActivityEntity MyActivityDataProperty
        {
            get { return internalMyActivityData; }
            set { internalMyActivityData = value; }
        }
     
        public CTDiagnosis()
        {
            InitializeComponent();
        }
     
        private void handleManagerSendBackEvent_Invoked(object sender, ExternalDataEventArgs e)
        {
            LocalEventArgs localEventArgs = (LocalEventArgs)e;
            internalMyActivityData.GotoCondition = localEventArgs.WorkFlowActivityEntityProperty.GotoCondition;
        }
    }

    获取workflow处理器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    /// <summary>
           /// 获取workflow处理器
           /// </summary>
           public static WorkflowRuntime CurrentWorkflowRuntime
           {
               get
               {
                   if (workflowRuntime == null)
                   {
                       workflowRuntime = new WorkflowRuntime();
                       //加载通讯服务
                       ExternalDataExchangeService dataService = new ExternalDataExchangeService();
                       workflowRuntime.AddService(dataService);
                       localService = new LocalService.LocalService();
                       dataService.AddService(localService);
     
                       //加载持久化服务
                       string connStr = System.Configuration.ConfigurationManager.AppSettings["WF.PersistenceDB.ConnectionString"].ToString();
                       SqlWorkflowPersistenceService WorkflowPersistenceService =
                           new SqlWorkflowPersistenceService(connStr);
                       //bool unloadOnIdle = false;
                       //TimeSpan instanceOwnershipDuration = new TimeSpan(0, 0, 3);
                       //TimeSpan loadingInterval = new TimeSpan(0, 0, 1);
                       //SqlWorkflowPersistenceService WorkflowPersistenceService =
                       //     new SqlWorkflowPersistenceService(connStr, unloadOnIdle, instanceOwnershipDuration, loadingInterval);
                       //NameValueCollection parms = new NameValueCollection();
                       //parms.Add("UnloadOnIdle", "true");
                       //parms.Add("ConnectionString", connStr);
                       //SqlWorkflowPersistenceService WorkflowPersistenceService =
                       //    new SqlWorkflowPersistenceService(parms);
                       workflowRuntime.AddService(WorkflowPersistenceService);
     
                       //相应流程事件
                       workflowRuntime.WorkflowIdled += OnWorkflowIdled;
                       workflowRuntime.WorkflowStarted += OnWorkflowStarted;
                       workflowRuntime.WorkflowTerminated += OnWorkflowTerminated;
                       workflowRuntime.WorkflowCompleted += OnWorkflowCompleted;
     
     
                       ////加载跟踪服务
                       //SqlTrackingService sqlTrackingService = new SqlTrackingService(DBAccess.connectionString);
                       //sqlTrackingService.IsTransactional = false;
                       //workflowRuntime.AddService(sqlTrackingService);
     
                       workflowRuntime.StartRuntime();
     
                   }
     
                   return workflowRuntime;
               }
           }
    Runtime 服务

    WorkflowRuntime类仅仅提供了执行工作流的基本功能,之前我们提到的一些重要功能(比如跟踪工作流)则可以通过WorkflowRuntime提供的扩展性机制-AddService方法来实现.

    AddService允许我们向Runtime中添加可用的服务.这些服务可以是我们为特定领域编写的自定义服务,也可以是WF中内置的服务.

    调度服务 Scheduling Services

    调度服务用来控制Runtime执行工作流所需要的线程.

    DefaultWorkflowSchedulerService会创建新的线程来执行工作流.因为工作流和宿主应用程序的线程是分开的,所以工作流是异步执行的并且不会阻止任何应用程序的线程.我们还可以配置允许同时执行的工作流最大数量.

    当宿主应用程序可以转让线程给工作流Runtime时可以使用另外一个调度服务-ManualWorkflowSchedulerService.对服务器端应用程序(比如ASP.NET Web应用程序和Web Service)而言,把线程转让给Runtime非常有用.服务器端应用程序通常的做法是为每个客户端请求的服务创建线程.而宿主应用程序把线程”借给”WF Runtime的意义在于可以让Runtime在每个请求的线程上同步地执行工作流,而不是为每个请求创建两个线程.

    和Windows Worklow的所有服务一样,如果内置的服务不能满足你的需求,你可以定义你自己的调度服务.

    事务服务 Transaction Services

    事务服务允许Runtime保持位于工作流内部和持久存储器(durable store)中的状态的一致性.默认的事务服务是DefaultWorkflowTransactionService类的实例.正在运行的工作流进程中的活动和此服务共享相同的进程和相同的事务上下文.

    WF依靠.NET中的System.Transactions名称空间来实现事务机制. Transactions类提供一个轻量级的, auto-enlisting并且可提升的事务.事务像本地事务一样启动,然后Runtime可以根据需要把它提升为重量级的分布式事务.

    持久化服务 Persistence Services

    持久化服务负责把工作流状态保存到持久储存器.SqlWorkflowPersistenceService会把工作流状态保存到SQL Server数据库.长时间运行的工作流需要持久化服务,因为我们不能让处理订货单的工作流在内存里驻留30天直到客户支付才从内存中卸载.相反,Runtime应该保持工作流的状态到持久存储器中,并且把工作流实例从内存中卸载.在这30天中,Runtime可以重新加载工作流实例并恢复运行.当持久化服务启用时,WF Runtime会自动保持工作流空闲或者暂停等状态.

    SqlWorkflowPersistenceService支持SQL Server 2000以及更高版本(还包括免费的MSDE和Express版).当然,我们还需要一个数据库架构来让持久化服务知道如何去保存工作流状态,这部分内容将在后面的章节详述.

    跟踪服务 Tracking Services

    当调度服务选择了工作流运行的线程之后,跟踪服务就会负责监视并记录工作流的执行信息.跟踪服务使用Tracking Profile来通知Runtime它需要的工作流信息的类型.跟踪服务还可以打开跟踪频道(Tracking Channel)来接收事件和数据.WF包含一个SqlTrackingService类,这个类可以将跟踪数据存储到SQL Server数据库.跟踪服务将使用事务服务来确保工作流的跟踪数据与被跟踪工作流的状态一致.默认Runtime不会启动跟踪服务,但我们可以用编程的方式添加跟踪服务(或使用应用程序配置文件配置跟踪服务).

    获取workFlow的模板

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /// <summary>
    /// 获取workFlow的模板
    /// </summary>
    /// <param name="workFlowName"></param>
    /// <returns></returns>
    private Type GetWorkFlowType(string workFlowName)
    {
        Type wfType = null;
        if (workFlowName.Equals("Diagnosis", StringComparison.OrdinalIgnoreCase))
            wfType = typeof(CTDiagnosis);
        return wfType;
    }

    获取workflow 的实例ID

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    /// <summary>
    /// 获取workflow 的实例ID
    /// </summary>
    /// <param name="workflowName"></param>
    /// <param name="startParameter"></param>
    /// <returns></returns>
    public Guid NewWorkflow(string workflowName, object startParameter)
    {
        Dictionary<string, object> inputParameters = new Dictionary<string, object>();
        inputParameters.Add("MyActivityDataProperty", startParameter);
     
        //启动一个新的工作流
        WorkflowInstance workflowInstance = CurrentWorkflowRuntime.CreateWorkflow(GetWorkFlowType(workflowName), inputParameters);
        workflowInstance.Start();
     
        //重新从持久化数据库中加载工作流,这是必须的,否则GetLoadedWorkflows无法获得新加入的流程。
        CurrentWorkflowRuntime.GetWorkflow(workflowInstance.InstanceId);
        //ReloadWorkflow();
     
        return workflowInstance.InstanceId;
    }

    获取workflow的状态

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /// <summary>
    /// 获取workflow的状态
    /// </summary>
    /// <param name="instanceId"></param>
    /// <returns></returns>
    public string GetInstanceStateByInstanceId(Guid instanceId)
    {
        string strStatus = "";
        StateMachineWorkflowInstance smwi = new StateMachineWorkflowInstance(WorkflowMgr.CurrentWorkflowRuntime, instanceId);
        strStatus = smwi.CurrentStateName;
        return strStatus;
    }

    总结

    状态机工作流的持久化很重要,要不workflow重启时,得不到正确的状态.

    参考文献

    《WF编程》系列之4 - 漫游工作流:Widows Workflow Runtime及其服务   http://www.cnblogs.com/xiaoshatian/archive/2007/03/30/693687.html

    欢迎各位参与讨论,如果觉得对你有帮助,请点击image    推荐下,万分谢谢.

    作者:spring yang

    出处:http://www.cnblogs.com/springyangwc/

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    Mongodb新增的聚合方法及其Java客户端
    转载:mongoDB java驱动学习笔记
    笔记:Java反射以及动态代理
    转载:在恰当的地方使用MongoDB的WriteConcern.SAFE参数
    去Oracle事件(转)
    笔记:J2EE核心模式(待补充)
    笔记:MongoDB 基础学习
    转载:PostgreSQL SQL的性能调试 方法3-- 查 看 执 行 计 划
    转载: PostgreSQL SQL的性能调试方法2--数据库log分析
    matlab怎么设置默认路径
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2345003.html
Copyright © 2011-2022 走看看