WF Workflow 状态机工作流 开发

摘要:
我们知道,WF包括两种类型的工作流:顺序工作流和状态机工作流。工作流从初始状态开始,到终止状态结束。定义在两种状态之间转换的行为。通常,状态机工作流会对事件做出反应,事件的发生会改变状态。在线诊断的业务流程图。现在让我们看看WF状态设计图。新工作流的顺序图如下:WFworkflow价值转移模式?

概述

工作流是对业务流程的建模,当我们设计工作流的时候,我们首先要分析业务处理过程中要经历的步骤。然后,我们就可以利用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
publicsealedpartialclassCTDiagnosis : StateMachineWorkflowActivity
{
    privateWorkFlowActivityEntity internalMyActivityData;
 
    publicWorkFlowActivityEntity MyActivityDataProperty
    {
        get{ returninternalMyActivityData; }
        set{ internalMyActivityData = value; }
    }
 
    publicCTDiagnosis()
    {
        InitializeComponent();
    }
 
    privatevoidhandleManagerSendBackEvent_Invoked(objectsender, 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>
       publicstaticWorkflowRuntime CurrentWorkflowRuntime
       {
           get
           {
               if(workflowRuntime == null)
               {
                   workflowRuntime = newWorkflowRuntime();
                   //加载通讯服务
                   ExternalDataExchangeService dataService = newExternalDataExchangeService();
                   workflowRuntime.AddService(dataService);
                   localService = newLocalService.LocalService();
                   dataService.AddService(localService);
 
                   //加载持久化服务
                   stringconnStr = System.Configuration.ConfigurationManager.AppSettings["WF.PersistenceDB.ConnectionString"].ToString();
                   SqlWorkflowPersistenceService WorkflowPersistenceService =
                       newSqlWorkflowPersistenceService(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();
 
               }
 
               returnworkflowRuntime;
           }
       }
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>
privateType GetWorkFlowType(stringworkFlowName)
{
    Type wfType = null;
    if(workFlowName.Equals("Diagnosis", StringComparison.OrdinalIgnoreCase))
        wfType = typeof(CTDiagnosis);
    returnwfType;
}

获取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>
publicGuid NewWorkflow(stringworkflowName, objectstartParameter)
{
    Dictionary<string, object> inputParameters = newDictionary<string, object>();
    inputParameters.Add("MyActivityDataProperty", startParameter);
 
    //启动一个新的工作流
    WorkflowInstance workflowInstance = CurrentWorkflowRuntime.CreateWorkflow(GetWorkFlowType(workflowName), inputParameters);
    workflowInstance.Start();
 
    //重新从持久化数据库中加载工作流,这是必须的,否则GetLoadedWorkflows无法获得新加入的流程。
    CurrentWorkflowRuntime.GetWorkflow(workflowInstance.InstanceId);
    //ReloadWorkflow();
 
    returnworkflowInstance.InstanceId;
}

获取workflow的状态

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

总结

状态机工作流的持久化很重要,要不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/

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

免责声明:文章转载自《WF Workflow 状态机工作流 开发》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇uni-app使用DES加密解密数据iOS --获取当前时间和当前时间戳下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Azkaban简介和使用

概述 为什么需要工作流调度系统 l 一个完整的数据分析系统通常都是由大量任务单元组成: shell脚本程序,java程序,mapreduce程序、hive脚本等 l 各任务单元之间存在时间先后及前后依赖关系 l 为了很好地组织起这样的复杂执行计划,需要一个工作流调度系统来调度执行; 例如,我们可能有这样一个需求,某个业务系统每天产生20G原始数据,我们每天...

Linux中通过/proc/stat等文件计算Cpu使用率

Linux平台Cpu使用率的计算 proc文件系统 /proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为内核与进程提供通信的接口。用户和应用程序可以通过/proc得到系统的信息,并可以改变内核的某些参数。由于系统的信息,如进程,是动态改变的,所以用户或应用程序读取/proc目录中的文件时,proc文件系统是动态从系统...

守护线程会不会执行finally?默认情况new thread怎么样确定守护状态?

finally throw return 中,线程的状态及interrupt 守护线程在退出的时候并不会执行finnaly块中的代码 线程池造成服务器内存泄漏 中所述,新建线程默认上使用建立线程时的当前线程所处的守护状态 本文予以验证: package fin; /** * Created by joyce on 2019/12/16. */ pub...

Delphi管理多线程之线程局部存储:threadvar

尽管多线程能够解决许多问题,但是同时它又给我们带来了很多的问题。其中主要的问题就是:对全局变量或句柄这样的全局资源如何访问?另外,当必须确保一个线程中的某些事件要在另一个线程中的其他时间之前(或之后)发生时,该怎么办?这里将讲解通过使用由 Delphi提供的线程局部存储和 A P I为线程提供同步的方法。 这里先讲线程局部存储,下一篇再讲线程同步 线程局部...

java线程占多大的内存,占哪里的内存?

说到线程,我们往往想到的是线程安全、线程池,很少会去考虑线程的内存。 那么一个线程占用多大的内存?占用哪里的内存呢? 占多大的内存? jdk1.4默认的单个线程是占用256k的内存 jdk1.5+默认的单个线程是占用1M的内存 可以通过-Xss参数设定,一般默认就好 占哪里的内存? 这TM还用问?java线程当然是占用jvm的内存啊!(╯‵□′)╯︵┻━┻...

封装GCD以及介绍如何使用

源码地址 http://pan.baidu.com/s/1zTUR8 研究GCD有一段时间,翻译了多篇文章,找了很多的资料,看了很多官方文档,看起来很难,实际上很简单,本人一一进行讲解怎么使用. 支持ARC以及非ARC,无论在ARC环境还是在非ARC环境,都需要调用dispatchRelease方法来释放init出的GCDGroup,GCDQueue,G...