状态机是另外一种常见的工作流类型。它是以状态的变迁为驱动而进行业务流转的,是一定需要人为干预的,而不像顺序类型工作流那样可以按照事先设计好的业务流程一步一步依次执行下去。

一、状态机工作流范例

  State活动有三种状态类型:

  • 起始状态;
  • 业务逻辑过程状态;
  • 终止状态;

  在一个状态机工作流中起始状态和终止状态只能有一个。状态机工作流是从起始状态开始执行,在运行过程中通过业务员逻辑状态的变迁来进行工作流的流转,最终由终止状态标记工作流的结束。因此在状态机工作流设计界面上只能添加"State"状态活动,另外在该状态中还可以添加一个或多个"EventDriven(事件驱动活动)"。

  状态机工作流中大量使用HandleExternalEvent活动来接收应用程序的操作,从而改变工作流上运行表单的业务状态,因此需要定义一个接口程序作为工作流和应用程序之间沟通的桥梁。

  默认的状态机工作流界面图:

  

  在状态机工作流程序中需要指明哪个"State"活动是最先起始的活动,哪个"State"活动是最终结束的活动。

  

  可以通过点击"State"活动的右键菜单进行设置:

  

  通过拖动EventDriven活动左右两边的节点就可以建立状态间的变迁关系。

  工作流看似简单,实际上里面还要设置,双击每个EventDriven活动,为它添加一个HandleExternalEvent子活动,并将HandleExternalEvent子活动与接口项目中定义的事件依次绑定。

  

  Winform程序界面如下:

  

  其完成代码如下所示:

    public partial class Form1 : Form, ClassLibrary1.IEvent
{
public event EventHandler<ExternalDataEventArgs> Event1;
public event EventHandler<ExternalDataEventArgs> Event2;
public event EventHandler<ExternalDataEventArgs> Event3; public WorkflowRuntime workflowruntime;
private WorkflowInstance workflowinstance;
private ExternalDataExchangeService exterserv;
static AutoResetEvent waitHandle = new AutoResetEvent(false); //为了得到状态机工作流还运行中的变迁情况,例子使用了StateMachineInstanceStateHistory来获取状态机的状态。
//但使用"StateHistory"必须启动WWF工作流的"Persistence"和“Tracking”服务。
const string connectionTrackingString = "Initial Catalog=Tracking;Data Source=localhost;Integrated Security=SSPI;";
const string connectionPersistenceString = "Initial Catalog=SqlPersistenceService;Data Source=localhost;Integrated Security=SSPI;"; public Form1()
{
InitializeComponent(); workflowruntime = new WorkflowRuntime();
exterserv = new ExternalDataExchangeService(); workflowruntime.WorkflowIdled += OnWorkflowIdled;
workflowruntime.WorkflowCompleted += OnWorkflowCompleted; //分别创建"Persistence"与"Persistence"服务,并将它们加载到工作流的运行时容器Runtime中。
workflowruntime.AddService(new SqlTrackingService(connectionTrackingString));
WorkflowPersistenceService persistenceService = new SqlWorkflowPersistenceService(connectionPersistenceString);
workflowruntime.AddService(persistenceService); workflowruntime.AddService(exterserv);
exterserv.AddService(this); workflowruntime.StartRuntime(); Type wftype = typeof(WorkflowConsoleApplication1.Workflow1);
workflowinstance = workflowruntime.CreateWorkflow(wftype);
workflowinstance.Start();
} public void OnWorkflowIdled(object sender, WorkflowEventArgs e)
{
e.WorkflowInstance.TryUnload(); GetStateHistory addListItem = new GetStateHistory(GetStateHistorysync);
Invoke(addListItem, e.WorkflowInstance.InstanceId);
waitHandle.Set();
} public void OnWorkflowCompleted(object sender, WorkflowCompletedEventArgs e)
{
Addstring addListItem = new Addstring(Addstringsync);
Invoke(addListItem, "结束");
waitHandle.Set();
} private void btn1_Click(object sender, EventArgs e)
{
Event1(null, new ExternalDataEventArgs(workflowinstance.InstanceId));
this.btn1.Enabled = false;
} private void btn2_Click(object sender, EventArgs e)
{
Event2(null, new ExternalDataEventArgs(workflowinstance.InstanceId));
this.btn2.Enabled = false;
} private void btn3_Click(object sender, EventArgs e)
{
Event3(null, new ExternalDataEventArgs(workflowinstance.InstanceId));
this.btn3.Enabled = false;
} //将每一步的状态变化取出来显示在列表中。通过"委托"代理啊在工作流的"OnWorkflowIdled"事件中被调用。
private delegate void GetStateHistory(Guid id);
public void GetStateHistorysync(Guid id)
{
StateMachineWorkflowInstance StateMachineInstance = new StateMachineWorkflowInstance(workflowruntime, id);
ReadOnlyCollection<string> states = StateMachineInstance.StateHistory;
for (int i = states.Count; i > ; i--)
{
this.listView1.Items.Add(states[i - ].ToString());
}
} private delegate void Addstring(string str);
public void Addstringsync(string str)
{
this.listView1.Items.Add(str);
}
}

  运行后可以看到其状态的切换:

  

二、StateInitialization和StateFinalization活动

  在上面的例子中,我们看到了WorkflowStarted与WorkflowCompleted两个事件,分别代表工作流的启动与结束。但在"State"状态活动的属性窗口中却找不到相应的开始和结束事件。WWF专门为"State"活动设计了两个子活动"StateInitialization"和"StateFinalization"来实现相应的功能。

  状态机工作流都需要人为干预,因此都有对应的接口程序以便于HandleExternalEvent活动进行绑定。

  接口代码:

    [ExternalDataExchange]  //using System.Workflow.Activities;
public interface IEvent
{
event EventHandler<ExternalDataEventArgs> Event1;
}

  创建一个状态机工作流项目,在工作流设计界面上添加两个"State"活动,并且将其分别命名为"提交申请"和"结束",然后通过右键菜单将它们分别设置为工作流的"启动"和"终止"状态。
在"提交申请"状态中添加EventDriven子活动,并且在该EventDriven活动中添加HandleExternalEvent子活动,然后与接口项目中定义的"Event1"事件进行绑定。

  完成后的工作流界面如下所示:

  

  

  

  状态机工作流的"起始"类型状态和"业务逻辑过程"类型的状态可以添加"StateInitialization","StateFinalization"子活动,"终止"类型的状态是不能添加这两个子活动的。

  在右键菜单中通过"添加 StateInitialization"和"添加 StateFinalization",又或者从工具栏中将子活动直接添加到"State"活动中,"StateInitialization"和"StateFinalization"子活动只是一个普通的容器类型活动,它们会在"State"活动开始和结束时分别被触发,这就可以起到类似于Window窗体"Load"事件和"FormClosed"事件的作用。

   

  更好地观察"StateInitialization"和"StateFinalization"子活动,和EventDriven子活动之间的运行顺序,可以向这两个子活动里面分别添加一个Code,然后绑定一个弹出窗口事件。工作流代码如下:

    public sealed partial class Workflow1 : StateMachineWorkflowActivity
{
public Workflow1()
{
InitializeComponent();
} private void Code1Execute(object sender, EventArgs e)
{
MessageBox.Show("StateInitialization开始执行!");
} private void Code2Execute(object sender, EventArgs e)
{
MessageBox.Show("StateFinalization开始执行!");
} private void handleExternalExecute(object sender, ExternalDataEventArgs e)
{
MessageBox.Show("handleExternalEvent开始执行!");
}
}

  创建一个WinForm程序,只有一个按钮,界面如下:

  

  Winform程序代码如下:

    public partial class Form1 : Form, ClassLibrary1.IEvent
{
public event EventHandler<ExternalDataEventArgs> Event1; public WorkflowRuntime workflowruntime;
private WorkflowInstance workflowinstance;
private ExternalDataExchangeService exterserv;
static AutoResetEvent waitHandle = new AutoResetEvent(false); public Form1()
{
InitializeComponent(); workflowruntime = new WorkflowRuntime();
exterserv = new ExternalDataExchangeService(); workflowruntime.AddService(exterserv);
exterserv.AddService(this); workflowruntime.StartRuntime(); Type wftype = typeof(WorkflowConsoleApplication1.Workflow1);
workflowinstance = workflowruntime.CreateWorkflow(wftype);
workflowinstance.Start();
} private void btn1_Click(object sender, EventArgs e)
{
Event1(null, new ExternalDataEventArgs(workflowinstance.InstanceId));
}
}

  弹出对话框顺序如下,启动程序,未点按钮:

  

  点击提交按钮后:

    

  • StateInitialization:在工作流启动时执行;
  • StateFinalization:在工作流完成时执行;

WWF3状态机工作流<WWF第七篇>的更多相关文章

  1. WWF3追踪功能<WWF第六篇>

    WWF工作流提供了Tracking跟踪功能来对工作流实例及其所包含的活动在运行时的状态进行跟踪,以便用户在需要时可以通过这些历史信息进行分析.WWF的Tracking跟踪功能是通过"SqlT ...

  2. 第七篇 Integration Services:中级工作流管理

    本篇文章是Integration Services系列的第七篇,详细内容请参考原文. 简介在上一篇文章,我们创建了一个新的SSIS包,学习了SSIS中的脚本任务和优先约束,并检查包的MaxConcur ...

  3. 第七篇 SQL Server代理作业活动监视器

    本篇文章是SQL Server代理系列的第七篇,详细内容请参考原文 在这一系列的上一篇,你创建并配置SQL Server代理作业.每个作业有一个或多个步骤,可能包含大量的工作流.在这篇文章中,将查看作 ...

  4. 【译】第七篇 Integration Services:中级工作流管理

    本篇文章是Integration Services系列的第七篇,详细内容请参考原文. 简介在上一篇文章,我们创建了一个新的SSIS包,学习了SSIS中的脚本任务和优先约束,并检查包的MaxConcur ...

  5. 【译】第七篇 SQL Server代理作业活动监视器

    本篇文章是SQL Server代理系列的第七篇,详细内容请参考原文 在这一系列的上一篇,你创建并配置SQL Server代理作业.每个作业有一个或多个步骤,可能包含大量的工作流.在这篇文章中,将查看作 ...

  6. Workflow笔记2——状态机工作流

    状态机工作流 在上一节Workflow笔记1——工作流介绍中,介绍的是流程图工作流,后来微软又推出了状态机工作流,它比流程图功能更加强大. 状态机工作流:就是将工作流系统中的所有的工作节点都可以看做成 ...

  7. SharePoint 2013 状态机工作流之扩展自定义状态

    当我们使用SharePoint 2013的状态机工作流时,发现一个非常不爽的事情,就是SharePoint 所有的工作流状态,都是固定的那些,没办法显示我们自定义的状态,后来经过Google发现,原来 ...

  8. SharePoint 2013 状态机工作流之日常报销示例

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

  9. 解剖SQLSERVER 第七篇 OrcaMDF 特性概述(译)

    解剖SQLSERVER 第七篇  OrcaMDF 特性概述(译) http://improve.dk/orcamdf-feature-recap/ 时间过得真快,这已经过了大概四个月了自从我最初介绍我 ...

随机推荐

  1. PLSQL_Oracle Table Lock表级锁的处理(案例)

    20150506 Created By BaoXinjian

  2. win764上vs2010+opencv2.4.11安装配置

    1:准备工作 1)opencv的官网下载你所要版本的opencv库文件,运行安装解压到自定义的一个文件夹里(D:\Program Files). 2)安装vs2010. 二:配置 1.计算机环境变量: ...

  3. py继续

    这个正则里面有引号,我外面在一个引号就出问题了,应该怎么处理 用双引号

  4. 错误记录 git pull

    在安装open-falcon的nodata组件,更新库的时候,git pull 报错: You are not currently on a branch, so I cannot use any'b ...

  5. studio--问题

    2,Android studio 怎么能删除干净一个module? 工程→open module settings→选中你要删除的module,然后点“一”,确定后返回,即可在module邮件下看到d ...

  6. git重写历史记录

    1 修改上一次历史提交,替换掉上次的提交git commit --amend 2 git rebase 将不同分支路径合并到同一分支路径上eg:将master分支上的 conflic rebase合并 ...

  7. MongoDB Tool

    robomongo MongoBooster: [推薦]MongoChef:http://3t.io/mongochef/download/ MongoVUE 是个比较好用的MongoDB客户端,不过 ...

  8. EXPDP

    源地址:http://blog.csdn.net/zftang/article/details/6387325

  9. java小程序 示例

    乘法表: package com.test; import org.junit.Test; public class TestSwitch { @Test public void test() { f ...

  10. C#中List的Find方法的使用

    查找List中的某个值,可以使用循环遍历对比,查找出结果.C#中提供了Find方法,可以直接使用,只要查找条件传入就可.如下: public class RecordInfo { private st ...