WWF3的持续化<第五篇>

时间:2023-02-25 16:48:13

  WWF提供的持续化功能会自动记录工作流实例以及它包含的所有活动的执行状态,这些状态并不是指工作流上流转的表单所呈现的业务逻辑状态。WWF持续化功能就是将未执行完成的工作流实例以及该实例中各种活动的状态,以文件或数据库方式进行存储,待需要的时候再重新将其加载回工作流运行时容器Runtime中。运行完毕才删除。

  在具体操作中通过"SqlWorkflowPersistenceService"类来实现持续化的功能,基于数据库,其他数据库需重新实现接口。

一、创建SqlPersistenceService数据库

  要在SQLServer实现工作流的保存、恢复功能,需要创建一些相关表与存储过程。默认情况下在C:\Windows\Microsoft.NET\Framework\v3.5\SQL\EN 路径下有SqlPersistenceProviderSchema.sql和SqlPersistenceProviderLogic.sql两个文件,打开SQLServer创建一个名叫SqlPersistenceService的数据库,按顺序执行以上两个sql脚本。此时,SqlPersistenceService数据库就创建了几个表与存储过程。

  如果实在不行,就把SqlPersistenceService数据库附加进来。http://files.cnblogs.com/kissdodog/WWF%E6%8C%81%E7%BB%AD%E5%8C%96%E6%95%B0%E6%8D%AE%E5%BA%93.rar

  接口如下:

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

  新建一个工作流如下:

  WWF3的持续化<第五篇>

  里面是3个HandleExternalEvent活动,分别于刚刚定义的接口事件相绑定。

  WWF3的持续化<第五篇>

  在bin目录里面添加一个XML文件,其代码如下:

<WorkflowInstances />

  新建一个Winform程序,界面如下:

  WWF3的持续化<第五篇>

  代码如下:

    public partial class Form1 : Form, ClassLibrary1.IEvent
{
//创建一个WinForm引用程序,然后继承并实现接口中定义的事件
public event EventHandler<ExternalDataEventArgs> PMApproved;
public event EventHandler<ExternalDataEventArgs> VPApproved;
public event EventHandler<ExternalDataEventArgs> StaffSubmit; private WorkflowRuntime runtime;
//SQLServer中的"SqlPersistenceService"数据库是用来存储工作流实例及其活动的运行状态。
//业务逻辑状态也能够以XML文件形式进行存储,当程序刚运行无流程在运行时,添加一个空xml文件
//名为:workflowInstances.xml直接放在bin目录
const string instanceFilename = "workflowInstances.xml"; WorkflowInstance instance; public Form1()
{
InitializeComponent(); this.runtime = new WorkflowRuntime(); runtime.WorkflowCompleted += new EventHandler<WorkflowCompletedEventArgs>(runtime_WorkflowCompleted);
runtime.WorkflowIdled += OnWorkflowIdled; //应用程序启动时以"SqlWorkflowPersistenceService"为对象来实例化"WorkflowPersistenceService"类,
//并通过"SqlWorkflowPersistenceService"来连接SQLServer数据库,同时将工作流的持续化服务加载到工作流运行时容器Runtime中。
WorkflowPersistenceService persistenceService =
new SqlWorkflowPersistenceService(
"server=CZZ;database=SqlPersistenceService;uid=sa;pwd=123");
runtime.AddService(persistenceService); ExternalDataExchangeService dataService = new ExternalDataExchangeService();
runtime.AddService(dataService); dataService.AddService(this); LoadWorkflowData(); runtime.StartRuntime(); }
//在工作流空闲状态时并将其从内存中卸载出去
//重载工作流的"WorkflowIdled"事件,当工作流处于等待状态下时将通过该事件来调用工作流实例的"TryUnload()"方法,
//使它激发工作流的"WorkflowPersisted"事件,这样工作流就可以通过"WorkflowPersistenceService"服务将信息自动保存到SQL Server数据库,以实现持续化功能。
static void OnWorkflowIdled(object sender, WorkflowEventArgs e)
{
e.WorkflowInstance.TryUnload();
} //当工作流完成后,将界面列表中的相应数据删除
//当工作流运行结束时还需要对界面列表中的相关信息进行删除,用户可以通过重载工作流的"WorkflowCompleted"事件来实现。
//要注意分清楚,事件是工作流的事件,而删除界面是WinForm程序的事。工作流与应用程序不在同一个线程,因此不能直接调用。这种情况可以通过委托来实现。
void runtime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e)
{
RemoveListViewItem remove = new RemoveListViewItem(RemoveListViewItemAsync);
Invoke(remove, e.WorkflowInstance.InstanceId);
}
private delegate void RemoveListViewItem(Guid instanceId);
private void RemoveListViewItemAsync(Guid instanceId)
{
foreach (ListViewItem item in ListViewExisting.Items)
{
if (item.SubItems[].Text.Equals(instanceId.ToString()))
ListViewExisting.Items.Remove(item);
}
} //用户提交请假单的按钮事件
private void btnSubmit_Click(object sender, EventArgs e)
{
instance = runtime.CreateWorkflow(typeof(WorkflowConsoleApplication1.Workflow1));
instance.Start(); StaffSubmit(null, new ExternalDataEventArgs(instance.InstanceId)); ListViewExisting.Items.Add(new ListViewItem(new String[] { instance.InstanceId.ToString(), this.txtDay.Text, "提交请假单" })); }
//当窗体关闭时,将列表中请假单的信息保存到XML中
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
SaveWorkflowData();
runtime.Dispose();
}
//项目经理审批的按钮
private void btnPMArrpoved_Click(object sender, EventArgs e)
{
instance = runtime.GetWorkflow(new Guid(ListViewExisting.SelectedItems[].Text)); PMApproved(null, new ExternalDataEventArgs(instance.InstanceId)); foreach (ListViewItem item in ListViewExisting.Items)
{
if (item.SubItems[].Text.Equals(instance.InstanceId.ToString()))
item.SubItems[].Text = "等待VP审批";
}
}
//副总经理审批的按钮
private void btnVPApproved_Click(object sender, EventArgs e)
{
instance = runtime.GetWorkflow(new Guid(ListViewExisting.SelectedItems[].Text));
VPApproved(null, new ExternalDataEventArgs(instance.InstanceId));
foreach (ListViewItem item in ListViewExisting.Items)
{
if (item.SubItems[].Text.Equals(instance.InstanceId.ToString()))
item.SubItems[].Text = "审批通过";
}
}
#region 读写XML的方法
/// <summary>
/// 从XML文件中读取已经钝化的工作流实例的信息
/// </summary>
public void LoadWorkflowData()
{
XmlTextReader reader = new XmlTextReader(instanceFilename);
try
{
while (reader.Read())
{
if (reader.Name.Equals("WorkflowInstance"))
{
ListViewExisting.Items.Add(
new ListViewItem(
new String[] { reader.GetAttribute("InstanceId"),
reader.GetAttribute("Day"),
reader.GetAttribute("State")}));
}
}
reader.Close();
}
catch (FileNotFoundException) { }
}
/// <summary>
/// 保存工作流实例的信息到XML文件中
/// </summary>
public void SaveWorkflowData()
{
XmlTextWriter writer = new XmlTextWriter(instanceFilename, Encoding.Unicode);
writer.WriteStartElement("WorkflowInstances");
foreach (ListViewItem item in ListViewExisting.Items)
{
writer.WriteStartElement("WorkflowInstance");
writer.WriteAttributeString("InstanceId", item.SubItems[].Text);
writer.WriteAttributeString("Day", item.SubItems[].Text);
writer.WriteAttributeString("State", item.SubItems[].Text);
writer.WriteEndElement();
}
writer.WriteEndElement();
writer.Flush();
writer.Close();
}
#endregion
}

  执行效果如下:

  WWF3的持续化<第五篇>

  由于在关闭窗口的时候,会将当前工作流的执行状态保存到XML文件和数据库中,而下次打开的时候,回去读取上次执行到的状态,所以当工作流执行到某一步关闭窗口再打开,会显示上次保存的状态。

WWF3的持续化<第五篇>的更多相关文章

  1. 【Python五篇慢慢弹(4)】模块异常谈python

    模块异常谈python 作者:白宁超 2016年10月10日12:08:31 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给出的pythondo ...

  2. 前端工程师技能之photoshop巧用系列第五篇——雪碧图

    × 目录 [1]定义 [2]应用场景 [3]合并[4]实现[5]维护 前面的话 前面已经介绍过,描述性图片最终要合并为雪碧图.本文是photoshop巧用系列第五篇——雪碧图 定义 css雪碧图(sp ...

  3. WWF3追踪功能&lt&semi;WWF第六篇&gt&semi;

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

  4. ElasticSearch入门 第五篇:使用C&num;查询文档

    这是ElasticSearch 2.4 版本系列的第五篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 E ...

  5. 持续化集成Jenkins的系统配置

    最近在研究selenium2自动化测试,用到持续化集成jenkins.由于之前仅限于使用,而没有真正动手配置过,所以现在学习从零开始,搭建持续化集成,故而有了这篇博客. 先介绍一下项目持续集成测试,这 ...

  6. mysql第五篇 &colon; MySQL 之 视图、触发器、存储过程、函数、事物与数据库锁

    第五篇 : MySQL 之 视图.触发器.存储过程.函数.事物与数据库锁 一.视图 视图是一个虚拟表(非真实存在的),其本质是‘根据SQL语句获取动态的数据集,并为其命名‘ ,用户使用时只需使用“名称 ...

  7. 【Python五篇慢慢弹】快速上手学python

    快速上手学python 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多 ...

  8. 【Python五篇慢慢弹】数据结构看python

    数据结构看python 作者:白宁超 2016年10月9日14:04:47 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给出的pythondoc ...

  9. 【Python五篇慢慢弹(3)】函数修行知python

    函数修行知python 作者:白宁超 2016年10月9日21:51:52 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给出的pythondoc ...

随机推荐

  1. 2016年中国大学生程序设计竞赛(合肥)-重现赛1009 HDU 5969

    最大的位或 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  2. Kostya the Sculptor

    Kostya the Sculptor 题目链接:http://codeforces.com/problemset/problem/733/D 贪心 以次小边为第一关键字,最大边为第二关键字,最小边为 ...

  3. c&num;抽取pdf文档标题(2)

    public class IETitle { public static List<WordInfo> WordsInfo = new List<WordInfo>(); pr ...

  4. JIRA的邮件通知

    提交测试或提交上线申请时发送给相关的开发人员.测试人员.运维人员. 使用插件Notification

  5. 适用于Mac 的自动补丁管理软件

    适用于Mac 的自动补丁管理软件 ManageEngine Desktop Central 的功能越来越神奇.系统管理员现在可以使用 Desktop Central 管理异构网络.即使是最复杂的任务, ...

  6. &lowbar;event&lowbar;worldstate&lowbar;team

    EventId 事件ID ID WorldStateUI.dbc第10列数字部分 TeamId 事件玩家分组,攻守(防守为1,进攻为2),自定义阵营(_faction表自定义阵营ID),公会(公会gu ...

  7. django源码解析之 BooleanField &lpar;三&rpar;

    def __init__(self, *args, **kwargs): kwargs['blank'] = True if 'default' not in kwargs and not kwarg ...

  8. Eclipse中如何改变主题

    童鞋们, eclipse主题太丑?想设置护眼的主题? 看看这些主题: 请移驾: Eclipse Color Themes 怎么设设置? 1. 打开”eclipse marketplace“, 如下图: ...

  9. (剑指Offer)面试题52:构建乘积数组

    题目: 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1].不能 ...

  10. 【DQ冰淇淋】—— Babylon 冰淇淋三维互动营销项目总结

    前言:在学习过Babylon.js基础之后,我上手的第一个网页端3D效果制作项目就是‘DQ冰淇淋’.这个小项目应用到了Babylon最基础的知识,既可以选味道,选点心,也可以旋转.倒置冰淇淋,互动起来 ...