Workflow笔记3——BookMark和持久化

BookMark

我们在平时的工作流使用中,并不是直接这样一气呵成将整个工作流直接走完的,通常一个流程到了某一个节点,该流程节点的操作人,可能并不会马上去处理该流程,而只有当处理人处理了该流程,流程才会继续往下走。对于不同流程节点的处理人,他所能处理的是不同的流程节点。

就好像我们看书,我们需要书签来标识,我现在已经看到哪个地方了,工作流也是一样的,我需要通过书签,来确定不同角色的人能处理的是哪一个流程。

1、在项目WindowsWorkFlowApp中,新建“代码活动” BookMarkCodeActivity

修改继承类为NativeActivity,Execute方法的参数类型变为NativeActivityContext类型了。代码如下:

    public sealed class BookMarkCodeActivity : NativeActivity
    {
        // 定义一个字符串类型的活动输入参数
        public InArgument<string> BookMarkName { get; set; }
        //定义一个输出参数,用来做流程判断,相当于模拟用户处理流程节点的操作
        public OutArgument<int> Num { get; set; }

        // 创建一个BookMark,让流程停下来
        protected override void Execute(NativeActivityContext context)
        {
            // 1.获取BookMark名称
            string strBookMarkName = context.GetValue(BookMarkName);
            // 2.创建BookMark
            context.CreateBookmark(strBookMarkName,new BookmarkCallback(PreExecuteWorkFlow));
        }
        /// <summary>
        /// 注意,一定要记得注意重写此属性,并返回true,否则后面运行会报错
        /// </summary>
        protected override bool CanInduceIdle
        {
            get
            {
                return true;// base.CanInduceIdle;
            }
        }
        /// <summary>
        /// 继续执行下一个状态前,必须先执行该方法。
        /// </summary>
        /// <param name="context"></param>
        /// <param name="bookmark">书签</param>
        /// <param name="value">传递过来的值</param>
        public void PreExecuteWorkFlow(NativeActivityContext context, Bookmark bookmark, object value)
        {
            context.SetValue(Num, Convert.ToInt32(value));
        }
}

2、生成项目WindowsWorkFlowApp

3、双击State1打开,将代码活动添加到State1中,并创建变量Vnum。

4、创建输入参数InputBookMarkName

5、改造Form1窗体

修改启动工作流的代码:

将以WorkflowApplication app;提取到类下面。

            app = new WorkflowApplication(new Activity1(), new Dictionary<string, object>() {
            {"InputName","神刀张三"},{"InputBookMarkName",txtBookMarkName.Text}
            });
            app.Idle = delegate(WorkflowApplicationIdleEventArgs er)
            {
                Console.WriteLine("工作流 {0} 空闲.", er.InstanceId);
                syncEvent.Set(); //这里要唤醒,不让的话,当创建了一个书签之后,界面就卡死了。
            };

为“继续执行”按钮添加代码

        //唤醒BookMark执行流程
        private void btnContinue_Click(object sender, EventArgs e)
        {
            //这里会调用PreExecuteWorkFlow方法,并将txtNum的值传过去
            app.ResumeBookmark(txtBookMarkName.Text, int.Parse(txtNum.Text));
        }

6、双击T1进行修改,添加条件判断

假设VNum变量的值等于5,则继续往下执行State2。

7、添加T3,当VNum变量的值不等于5,再回到State1。

双击T3,添加条件

8、运行结果如下:

工作流持久化

1、通过创建一个数据库来持久保存工作流实例。新建数据库WorkFlowDB:

CREATE DATABASE [WorkFlowDB]
 CONTAINMENT = NONE
 ON  PRIMARY
( NAME = N‘WorkFlowDB‘, FILENAME = N‘G:\DataBase\WorkFlowDB.mdf‘ , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
 LOG ON
( NAME = N‘WorkFlowDB_log‘, FILENAME = N‘G:\DataBase\WorkFlowDB_log.ldf‘ , SIZE = 2048KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO

2、然后新建表来存储工作流的实例数据,如何新建表?

到%WINDIR%\Microsoft.NET\Framework\v4.xxx\SQL\EN 文件夹下面去寻找脚本,按Win+R,运行%WINDIR%\Microsoft.NET\Framework

找到这两个SQL脚本之后,在数据库WorkFlowDB中首先运行 SqlWorkflowInstanceStoreSchema.sql 文件,然后运行 SqlWorkflowInstanceStoreLogic.sql 文件。执行完成之后,就会在数据库WorkFlowDB中新建如下表。

InstancesTable表就是用来存储工作流实例的表。

3、在项目WindowsWorkFlowApp中,添加如下两个程序集的引用

4、修改工作流启动代码

引入命名空间

using System.Activities.DurableInstancing;  

修改btnStartWorkFlow_Click代码:

            SqlWorkflowInstanceStore store =
    new SqlWorkflowInstanceStore(@"Server=.\MSSQLSERVER2012;database=WorkFlowDB;uid=sa;pwd=yujie1127);
            app.InstanceStore = store;

只需要这两行代码,就可以执行持久化工作。那么当下次重新打开工作流的时候,我需要从数据库中找到是那一条工作流实例数据,为了演示简单,我这里就将工作流实例的主键直接放到From窗体界面展示,而通常在工作中,我们是会用数据表来专门存储这些数据信息的。

5、改造Form1代码,修改btnContinue_Click

using System;
using System.Activities;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Forms;

using System.Activities.DurableInstancing;  

namespace WindowsWorkFlowApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        static readonly string ConnStr=@"Server=.\MSSQLSERVER2012;database=WorkFlowDB;uid=sa;pwd=yujie1127";
        //WorkflowApplication app;
        AutoResetEvent syncEvent = new AutoResetEvent(false);
        private void btnStartWorkFlow_Click(object sender, EventArgs e)
        {
            WorkflowApplication app = new WorkflowApplication(new Activity1(), new Dictionary<string, object>() {
            {"InputName","神刀张三"},{"InputBookMarkName",txtBookMarkName.Text}
            });

            SqlWorkflowInstanceStore store =
    new SqlWorkflowInstanceStore(ConnStr);
            app.InstanceStore = store;
            txtID.Text = app.Id.ToString();

            WorkFlowEvent(app, syncEvent);

            app.Run();

            syncEvent.WaitOne();
        }

        private static void WorkFlowEvent(WorkflowApplication app, AutoResetEvent syncEvent)
        {
            #region 工作流生命周期事件
            app.Unloaded = delegate(WorkflowApplicationEventArgs er)
            {
                Console.WriteLine("工作流 {0} 卸载.", er.InstanceId);
            };
            app.Completed = delegate(WorkflowApplicationCompletedEventArgs er)
            {
                Console.WriteLine("工作流 {0} 完成.", er.InstanceId);
                syncEvent.Set();
            };
            app.Aborted = delegate(WorkflowApplicationAbortedEventArgs er)
            {
                Console.WriteLine("工作流 {0} 终止.", er.InstanceId);
            };
            app.Idle = delegate(WorkflowApplicationIdleEventArgs er)
            {
                Console.WriteLine("工作流 {0} 空闲.", er.InstanceId);
                syncEvent.Set(); //这里要唤醒,不让的话,当创建了一个书签之后,界面就卡死了。
            };
            app.PersistableIdle = delegate(WorkflowApplicationIdleEventArgs er)
            {
                Console.WriteLine("持久化");
                return PersistableIdleAction.Unload;
            };
            app.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs er)
            {
                Console.WriteLine("OnUnhandledException in Workflow {0}\n{1}",
       er.InstanceId, er.UnhandledException.Message);
                return UnhandledExceptionAction.Terminate;
            };
            #endregion
        }

        //唤醒BookMark执行流程
        private void btnContinue_Click(object sender, EventArgs e)
        {
            #region old code
            //这里会调用PreExecuteWorkFlow方法,并将txtNum的值传过去
            //app.ResumeBookmark(txtBookMarkName.Text, int.Parse(txtNum.Text));
            #endregion

            WorkflowApplication app = new WorkflowApplication(new Activity1());

            SqlWorkflowInstanceStore store =
    new SqlWorkflowInstanceStore(ConnStr);
            app.InstanceStore = store;

            WorkFlowEvent(app, syncEvent);

            app.Load(Guid.Parse(txtID.Text)); //加载工作流实例
            //继续执行此工作流实例
            app.ResumeBookmark(txtBookMarkName.Text, int.Parse(txtNum.Text));
        }
    }
}

6、我们看数据表中已经多了一条工作流实例数据

7、然后关闭应用程序,再重新启动

从数据库中找到这个ID,然后填写上。

我们看到整个工作流执行完成了,在来看数据表中的工作流实例数据已经删除了。

源码下载:WorkflowConsoleApp3.zip

时间: 2024-07-31 07:31:59

Workflow笔记3——BookMark和持久化的相关文章

Workflow笔记2——状态机工作流(转)

出处:http://www.cnblogs.com/jiekzou/p/6192813.html 在上一节Workflow笔记1——工作流介绍中,介绍的是流程图工作流,后来微软又推出了状态机工作流,它比流程图功能更加强大. 状态机工作流:就是将工作流系统中的所有的工作节点都可以看做成一个状态节点.每个节点都有N个状态,其中都包含初始状态.进入状态.离开状态等.当节点的状态变化的时候会执行某个节点. 新建项目StatueWorkflowConsoleApp 自动添加了一个起始节点和一个状态节点.

Workflow笔记二

状态机工作流 在上一节Workflow笔记1——工作流介绍中,介绍的是流程图工作流,后来微软又推出了状态机工作流,它比流程图功能更加强大. 新建项目StatueWorkflowConsoleApp 自动添加了一个起始节点和一个状态节点. 运行结果如下: 注意执行顺序.接下来,扩展此工作流. 1.设置全局变量Num 2.双击T1,为变量Num赋值 new Random().Next(0,10) 运行结果如下: 启动工作流 之前我们新建的工作流项目,都是通过如下方式来启动工作流的. Activity

Hibernate笔记——2.深入理解持久化对象

持久化类的要求 Hibernate对于持久化类的要求非常少. 它需要提供一个无参数的构造器,以便hibernate能够创建持久化实例.至少应该是包可见的. 提供一个标识属性,一般为数据库表的主键字段. 每个成员变量需要有set与get方法. 是非final类,以便Hibernate能够生成代理. 重写equals和hashCode方法:如果需要把持久化类放入Set中需要重写. 持久化类的状态 瞬态:对象被new出来但尚未与session关联.瞬态对象不会被持久化到数据库中,也不会被赋予持久化标识

Workflow笔记一

什么是工作流? 工作流(Workflow),是对工作流程及其各操作步骤之间业务规则的抽象.概括.描述.BPM:是Business Process Management的英文字母缩写.即业务流程管理,是一套达成企业各种业务环节整合的全面管理模式. 工作流软件,顾名思义,就是业务信息数据在多个环节模块之间的流转.企业内部业务种类非常多.变化也非常多.虽然业务变化非常多,但是流程的控制基本是不变的.我们常说的工作流或者是“流程”就是指 控制流程流转的核心引擎. 市面常见的工作流开发框架如下所示. Wi

redis学习笔记——RDB和AOF持久化

为防止数据丢失,需要将 Redis 中的数据从内存中 dump 到磁盘,这就是持久化.Redis 提供两种持久化方式:RDB 和 AOF.Redis 允许两者结合,也允许两者同时关闭. RDB 可以定时备份内存中的数据集.服务器启动的时候,可以从 RDB 文件中恢复数据集. AOF(append only file) 可以记录服务器的所有写操作.在服务器重新启动的时候,会把所有的写操作重新执行一遍,从而实现数据备份.当写操作集过大(比原有的数据集还大),Redis 会重写写操作集. 值得一提的是

workflow笔记

1 概要介绍 1)什么是流程定义 ? 流程定义是按照bpmn2.0标准定义业务流程,将流程定义的文件(.bpmn和.png(不是必须的))部署到activiti中,activiti就可以管理该业务流程. 2)什么是流程实例 ? 参与者(可以用户,也可以程序)按照流程定义发起一个流程,这个流程就是一个流程实例 .流程定义的内容就是一个静态文件(.bpmn),流程实例的内容是该 流程的执行过程(动态). 3)如何启动一个流程实例 ? 常用方式:启动一个流程实例时指定一个业务标识. // 业务标识 ,

Navi.Component.工作流操作手册

1.概述 1.1组件简介 随着互联网发展越来越快,越来越多的办公,由纸制开始向电脑发展.而以前通过纸制的单据,也逐步搬到了电脑上,由计算机软件操作完成.由于某些流程不能由单人完成,必须由多个人协作完成,工作流组件由此而生. 工作流组件用于解决由多人协作,办理时间无法确定的流程.如OA系统中的发文和收文流程,即是工作流组件典型的应用 1.2应用场景 基于工作流组件的系统,如OA办公自动化系统,审批系统等.本组件特别针对中国大陆政府机构的OA,审批系统所开发 1.3面向对象 Net程序开发员 1.4

《Sams Teach Yourself Windows? Workflow Foundation in 24 Hours》读书笔记目录

目录 1 Part I - The Basics 1.1 Hour 1 - Understanding Windows Workflow Foundation 1.2 Hour 2 - A Spin Around Windows Workflow Foundation 1.3 Hour 3 - Learning Basic Hosting 1.4 Hour 4 - Learning Host-Workflow Data Exchange 1.5 Hour 5 - Creating an Esca

《WF in 24 Hours》读书笔记 - Hour 1 - Understanding Windows Workflow Foundation

1.1 Hour 1 - Understanding Windows Workflow Foundation 1.1.1 What workflow is in general A workflow is logic-consisting of one or more steps that are predicated by one or more conditions-that a system or person must perform to complete a function. Be