博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
工作流-----WorkFlow
阅读量:6324 次
发布时间:2019-06-22

本文共 6342 字,大约阅读时间需要 21 分钟。

我们都知道对于一个OA系统来说,最重要的也是不可或缺的一个重要环节那就是对于工作流的实现,为此,最近专门在学习如何使用WorkFlow,问前辈,前辈也说道K2工作流引擎挺不错,自己同时也翻阅了一些资料,但因为自己这个OA项目主要是采用微软的ASP.NET MVC 来开发的,所以还是决定使用微软的那一套WorkFlow工作流引擎。不得不说,微软在对于客户体验这方面做的还真是不错的。为了方面学习,我也是通过一个小案例来学习WorkFlow,在这里也拿出来和大家共同分享学习。

小案例(请假工作流)

说明:

1.程序集:system.Activities

2.Xaml文件:工作流文件设计的类型,最终会被处理为一个类

3.状态机工作流(开发中使用的类型)

首先:创建一个Windows窗体应用程序,命名WorkFlowDemo

注意:为了便于工作流的展示,把当前项目的属性-----》服务,把输入类型由Windows应用程序改为控制台应用程序

接下来,简单点设计一下窗体页面

设计一下流程图:(状态机控件在工具箱)对于其中的工具使用,可以自己简单学习,很容易上手

前期工作完成接下来就是代码实现的时候了,为窗体的单击按钮注册事件

1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Threading.Tasks; 9 using System.Windows.Forms;10 using System.Activities;11 12 namespace WindowsFormsApplication113 {14     public partial class Form1 : Form15     {16         public Form1()17         {18             InitializeComponent();19         }20 21        //创建一个工作流对象22         WorkflowApplication wfapp;23         private void btnsave_Click(object sender, EventArgs e)24         {25 26             //1.准备好工作流中需要的参数27             Dictionary
dict = new Dictionary
();//用来向工作流传递参数28 dict.Add("LeaveDays", int.Parse(txtDays.Text));29 30 //2.创建一个工作流应用对象31 wfapp = new WorkflowApplication(new LeaveActivity(), dict);32 33 34 //3.调用wfapp对象的Run方法35 wfapp.Run();36 }37 38 private void btnjinli_Click(object sender, EventArgs e)39 {40 bool result = radioButton1.Checked;41 42 //唤醒书签43 wp.ResumeBookmark("经理审批", result);44 }45 46 private void button2_Click(object sender, EventArgs e)47 {48 bool result = radioButton3.Checked;49 wp.ResumeBookmark("财务总监审批", result);50 }51 }52 }
View Code

这时,产生了工作流中一个重要的内容------书签(BookMark)

场景:在实际业务场景中,流程一般都是复杂的,不会一口气从开始走到最后,当在某一个需要暂停的时候,这时,书签很好的充当了这个使者,就好像我们平时看书,看到某一页突然有事要离开,但办完事回来还是要接着看的对不对,通常我们会在暂停的位置放置一个标签,等我们下次继续翻阅,可以很快的知道上一次暂停的位置。

步骤:

1.在项目中添加一个代码活动(CodeActivity),

【注意】

  1. 将继承的CodeActivity父类改成NativeActivity,
  2. 同时将Execute方法中的参数也要修改为NatveActivityContext
  3. 重写父类的CanIncludeIdIe属性

2.在该代码活动的Execute方法里创建书签

代码实现:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Activities;namespace WindowsFormsApplication1{    public sealed class WaitProcess :NativeActivity    {        //输出型参数        public OutArgument
Result { get; set; } //输入型参数 public InArgument
BookMarkName { get; set; } //重写父类的CanIncludeIdIe属性 protected override bool CanInduceIdle { get { return true; } } protected override void Execute(NativeActivityContext context) { //创建书签 context.CreateBookmark(context.GetValue(BookMarkName), FunCallBack); } private void FunCallBack(NativeActivityContext context, Bookmark bookmark, object value) { Console.WriteLine("工作流被唤醒"); context.SetValue(Result,Convert.ToBoolean(value)); } }}
View Code

操作结果:

点击提交申请

点击第一个审批(因为我在流程图那边设置了当天数<6时,经理审批同意后直接结束)

别急,做到这里,也只是完成了三分之一,因为你会发现当你点击提交申请,这时,关闭整个应用程序,当你下次访问,点击审批的时候,会报错,

这是为什么呢?因为你点击提交申请后退出,这时整个WorkFlowApplication对象也会被销毁,那么问题来了,如何做到工作流实例的具体化?

方案有很多种,你可以采用xml文件保存,也可以把它保存到数据库,而我将采取后面那种方式,那么你又会说了,数据库我该怎么设计,别担心,微软已经帮我们写好了SQL脚本,你只需要找到它们并执行一下就好了。

步骤:

步骤:

  1. 建立数据表

在C:\Windows\Microsoft.NET\Framework\v4.0.30319\SQL\en中可以找到两个微软写好的数据库脚本

 

然后数据库中先执行后者脚本,在执行前者脚本

将工作流对象往数据库中存储

引入命名空间:

using System.Activities.DurableInstancing;

using System.Runtime.DurableInstancing;

  1. 什么时候持久化工作流对象?

在工作流创建之后,为工作流对象注册一个事件:

wfapp.PersistableIdle += a => { return PersistableIdleAction.Unload; };

  1. 创建一个SqlWorkFlowInstanceStore对象

SqlWorkflowInstanceStore ss = new SqlWorkflowInstanceStore("server=.;daabase=WorkFlow;uid=sa;pwd=123;");

关联持久化的工作流对象和具体的存储实例

wfapp.InstanceStore = ss;

 

  1. 如何从数据库中加载未完成的工作流实例

创建一个存储实例对象和一个工作流对象,并将它们进行关联,

注意:重新new的WorkFlowApplication对象也要重新注册wfapp.PersistableIdle += a => { return PersistableIdleAction.Unload; };这个事件

最后调用WorkFlowApplication对象的Load(Guid guid)方法

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;using System.Activities;using System.Activities.DurableInstancing;using System.Runtime.DurableInstancing;namespace WindowsFormsApplication1{    public partial class Form1 : Form    {        public Form1()        {            InitializeComponent();        }        WorkflowApplication wfapp;        private void btnsave_Click(object sender, EventArgs e)        {              //1.准备好工作流中需要的参数            Dictionary
dict = new Dictionary
();//用来向工作流传递参数 dict.Add("LeaveDays", int.Parse(txtDays.Text)); //2.创建一个工作流应用对象 wfapp = new WorkflowApplication(new LeaveActivity(), dict); //在工作流创建之后,为工作流对象注册一个事件 wfapp.PersistableIdle += a => { return PersistableIdleAction.Unload; }; //关联持久化的工作流对象和具体的存储实例 SqlWorkflowInstanceStore ss = new SqlWorkflowInstanceStore("server=.;daabase=WorkFlow;uid=sa;pwd=123;"); wfapp.InstanceStore = ss; //3.调用wfapp的Run方法 wfapp.Run(); } private void button1_Click(object sender, EventArgs e) { //从数据中加载实例 SqlWorkflowInstanceStore ss = new SqlWorkflowInstanceStore("server=.;daabase=WorkFlow;uid=sa;pwd=123;"); wfapp = new WorkflowApplication(new LeaveActivity()); wfapp.PersistableIdle += a => { return PersistableIdleAction.Unload; }; wfapp.InstanceStore = ss; //wfapp.Load("CA15C81C-FE95-4B0B-B1F4-B5F1478BEF3C");//传入的是一个guid参数 bool result = radioButton1.Checked; //唤醒书签 wfapp.ResumeBookmark("经理审批", result); } }}
View Code

效果图:

你会发现在你的数据库表中多了一条记录,这时记录了你上一次未完成的操作(把这个Guid复制下来,放到按钮1审批的代码中Load方法中)因为是做测试用

 

第二次在运行,直接点击经理审批对应的审批按钮,你会发现:

同时数据库中的记录也不见了

 

好了,具体实现就这么多了,但是还存在一个问题,那就是对于某个按钮事件,你会发现重复性的代码太多了,不妨就自己去进行封装吧!做成一个属于自己的Helper!

最后,非常希望大家可以提出批评和建议。谢谢!

 

转载于:https://www.cnblogs.com/xrk1203/p/6681608.html

你可能感兴趣的文章
android编译系统makefile(Android.mk)写法
查看>>
MD5源代码C++
查看>>
Eclipse 添加 Ibator
查看>>
Linux中变量$#,$@,$0,$1,$2,$*,$$,$?的含义
查看>>
男人要内在美,更要外在美
查看>>
app启动白屏
查看>>
Hadoop集群完全分布式安装
查看>>
QString,char,string之间赋值
查看>>
MySql之基于ssl安全连接的主从复制
查看>>
informix的逻辑日志和物理日志分析
查看>>
centos 5.5 64 php imagick 模块错误处理记录
查看>>
apache中文url日志分析--php十六进制字符串转换
查看>>
浅谈代理
查看>>
基于jquery实现的超酷动画源码
查看>>
Factorialize a Number
查看>>
防HTTP慢速攻击的nginx安全配置
查看>>
Spring Boot2.0+中,自定义配置类扩展springMVC的功能
查看>>
参与博客编辑器改版,我的礼物 感谢51cto
查看>>
JavaWeb笔记——JSTL标签
查看>>
一些实用性的总结与纠正
查看>>