你还记得windows workflow foundation吗

很多年前,windows workflow foundation还叫WWF,而直译过来的名称让很多人以为它就是用来开发工作流或者干脆就是审批流的。

博主当年还是个懵懂的少年,却也知道微软不会大力推一个面向如此具象的业务场景的技术,于是特地找了一本《WF本质论》,当看到“程序即数据”这个论断时,被深深震撼了。可能这只是作者的随意一写,但当时正是泛型方法、lamda表达式、匿名委托啥的开始出现的时候,作者的这一说法在某种程度上暗合了博主平常的编程思想。于是逻辑与数据,算法与结构,它们之间的界限在我眼里,在我心里,开始以更诡异的方式模糊了起来。

然而之后并未在工作上使用过WF,因此博主也就不再关注此项技术。如今重新翻看,突然发现官方的Workflow Team blog最近的更新都是两年前了,网上的资料都是N年前的,而且大多数是教大家怎么用。为何要用,何处要用,基本上没有太多介绍。到了现如今,似乎也被微软抛弃了,为此我还专门在博问里提了下,也没人知道具体详情。

很少有看到专门使用wf进行开发的场景,好用与否,在小众的群体里抽样得出结论也就显得不怎么可靠了。似乎wf在sharepoint环境中用起来比较协调,由于博主对sharepoint没有研究过,所以对此不好评论。如若在纯代码环境下开发,用wf自带的一套activity能画出看似清晰的流程图,然而关键的和外部交互的环节却仍然避免不了,需要考虑的因素大部分仍然需要代码去完成;而各种条件下流程的走向,使用activity的条件判断,又让人觉得没有直接写代码来的方便,比如ifelse,用代码可能只要在一个方法体中就能完成,而在流程图中却要使用两个activity,如果其中再有交互跳转的话,流程图的复杂程度未必在代码之下,而后期维护也难说容易。

不妨非恶意的揣测,经过几年时间,微软慢慢觉得,将代码间原本隐晦的逻辑关系抽离出来变成看得见的“流程”,对程序员来说,未必有多大的意义,于是就减少了这方面的投入。当然你也可以认为wf已经很成熟了,不过即使如此,博主还是倾向认为此种所谓成熟是因为找不到改进的方向,虽然“成熟”,但不怎么好用。

but,wf并非一无是处,wf的bookmark(书签机制)是最区别于传统开发的特性,个人认为也是最重要的特性。传统开发时,我们时不常的会遇到这种情形:判断流程是否走到特定环节以便决定下一步操作,其实就是判断A\B\C\D\...等排列组合变数,它们之间可能也是相互关联的,只要流程没有继续流转,那么每次启动都要进行同样的判断;是否可以在各变数满足条件时生成一个标签,当我们发现这个标签存在时,就可以去找标签对应的环节,就能马上进行后续操作了。实际开发中,我们常设置一个冗余的标识字段起这个作用。但单个字段未必能完全标识一个环节,而且也显得不够直观。wf中的bookmark与上述的标签类似,本质上,它是对委托异步回调炉火纯青的应用,更自然的描述是在变数尚未符合条件时的一种“等待”,常用于与外部交互,在流程设计时,也不会像传统代码操作(查询、判断、更新)标签那样显得突兀(这些操作wf都在更底层帮我们处理了)。

开头说到微软推出wf的本意并非用于开发业务上的工作流,我们甚至可以将任意有逻辑顺序的一段代码“wf化”,然而从业务场景来讲,wf的很多概念能映射其中,毕竟抽象和具象,都逃不离流程二字。因此项目前期或工期紧张,需要快速开发的时候,wf也能帮助程序员梳理流程——在[对]业务流程尚不清晰的时候,你会发现这非常有用——就算日后摈弃wf,大部分代码都可以复用,而由于各环节明确的流转关系,代码重构也较为容易。博主就是因为这个原因,在目前的一个项目中使用了wf,下面我会简单介绍相关要点和个人理解。

版本控制也是它的一个亮点,这个就不细说了。

由于本人对wf钻研不深,所述难免有误,请各位同学批评指正。另,本文并不展示任何项目代码,只以行业一般流程,展示博主在开发过程中的思索。


本项目主干是一手房置购流程,涉及到认筹、认购、成交、租赁四个环节,需求简化后如下(图是用visio画的,画得很挫,一直没找到实线弧形箭头):

1、环节流转

2、流转时需审核(可跨级审核,若申请人本身是最后环节审核人则直接通过)

3、审核不通过时将退回发起环节;审核过程中,申请人也可撤消此次申请

4、单个环节也有不同状态,比如认购有已认购退认购两种状态,此类状态转换也需要审核;而内容变更也需要审核

5、同时至多只能存在一个审核中事项。比如认购内容变更审核中时,就不能发起转成交申请。

这是一个比较典型的工作流场景。刚接手这个项目时,我考虑用传统方式开发,不多久我发现自己在各种环节、状态、标识、互斥项间晕头转向,一团浆糊。即使流程图已经很清晰明白地摆在面前,将之赋予代码和数据,并使看似毫无关联的各块内容按照预期逻辑运行,似乎显得相当困难。特别是产品有时会一脸无奈地跟你说,认筹也可以转租赁,业务说的;隔天又说,不需要了。要维系代码之间“隐秘”的逻辑关系并快速应对需求变更,随着业务复杂度的提高,难度也更快的升高。

当然,对于熟练工来说,这点难度不算什么,毕竟我们每天都在做这种工作——将业务流程转化成层层调用的代码——我们还可以祭出设计模式、AOP、IOC、ORM啥的让代码看起来更清(fu)晰(za)。我们一直在接受面向对象、面向架构、面向服务的训练,而缺少真正面向流程编程的经验,我想这才是为什么微软当年会推广wf的原因(此为病句,意为强调)。

wf有三种内置流程:顺序流、Flowchart、StateMachine。本项目可考虑后两种,博主选择的是StateMachine,整出来的主流程如下:

看上去很凌乱,只能怪vs自带的wf设计器没有visio好用,其实上图就是第1幅流程图的wf版本。

再来看下每条连线的逻辑,以认购环节出去的连线为例,触发器如下:

可以看到,流程会依据外部信号决定下一步骤,流到下一个环节(转成交、转租赁),或者是退认购,这里还有变更的情况图中没放出来。最终会根据流程中各变量和参数值选择某个路线:

任何类型的审核不通过or申请人撤销就回到当前环节,和之前我们用visio画的流程图一样直观。不过,这里有个问题。博主刚接触statemachine时,选择entry还是trigger放置业务逻辑比较困惑,当时认为两者皆可,毕竟最终只是通过condition来指定状态的转变方向,用不着care condition在哪里生成;博主当时认为微软设计statemachine时,是将trigger当做bookmark activity的容器,以便于与外部决策进行交互,当然我们也可以将bookmark放在entry中,说到底这就是一个规范问题,不必深究。然而博主发现,若流程从一个state流向同一个state——即state指向自己——其实前后两个环节已不是同一个“实例”了 ,因此原state的变量等状态不会保存,entry会再次执行。为了避免这种状况,有停留在当前状态的情形,应该将业务逻辑写在entry中,不进入到触发后的流转,因为一旦流转,就算流转回当前状态,也是先出再进。当然,如果当前状态没有需要保留的信息,写在trigger亦可。

再来看看审核到底发生了什么。

这个更不用我多说了,不过我还是要多说两句。虽然上图很清晰地还原了对应的需求,但未必是最合适的做法,我最后还是将这些逻辑统一到一个activity里。前面说过,我们能将绝大多数多行代码wf化,but,复杂的流程需要借助wf,一个简单方法就能搞定的逻辑如果还硬要画出几道条条理理来,那就是偏执了。(话说,写程序的大多数人都是偏执的,非黑即白,我没说错吧)

对于前述需求的第5条,单条wf流程天生就能满足,不需要我们做额外的coding。思考一下,若几个审核可以并行,或流程流转到下一环节后,上一环节需要变更了,怎么办?用多流程或子流程试试吧。


代码活动中普通的成员变量,持久化在bookmark恢复后,值丢失不可用;若需要在持久化前后保持变量值,应该使用Variable,或应用Serializable特性,两者都是博主推测没试过。

有些事务不能失败了就全部回退重来,比如单据状态从a->b,经过多位领导审批同意后,结果因为最后一步提交不成功,让单据回退到a重审?这种情况,只能将最后一步重新提交,实际开发中,可将此类“脏提交”定时再提交。

一个activity里可create多个bookmark,当所有bookmark都恢复执行后,流程才继续往下。

wf在流程流转过程中,并不能返回数据给调用者,比如发起认筹转认购的申请,调用ResumeBookmark方法,并不能知晓是直接通过还是等待审核,需要另外查数据库得到状态结果。当然可以使用WorkflowApplication.Extensions与外部程序交互,但不能满足某些场景,比如客户端调用webapi,服务端action发起流程,action自然需要知道流程跑完后(暂停or完结)的结果是什么并返回给客户端;这时候WorkflowApplication.Extensions就然并卵了,除非改写底层,比如让wf能取消action的后续执行并将结果数据写入http连接。

流程改版or外部依赖项变化,wf下,要么新旧版本并行,要么研究如何将旧版本迁移到新版本,很多情况下没有纯代码控制来得方便。

博主观点:同步SaaS并非wf较适用的场景,wf适用于异步消息推送场景,比如外卖点餐状态、快递状态、银行资金流转等,客户端并不等待马上的结果,而是事项状态改变时接收服务端消息即可。当然硬要在同步环境下使用也可以,此时需要更松散的设计和底层框架的配合,以适应wf“封闭式流程”的特点。


需继续研究的点:

1、有些流程大同小异,能否封装成一个可配置的流程,在设计时进行简单的参数配置就能显示不同的流程步骤;比如a状态可转为b、c状态,而b只能转c状态,那么a,b在转换到下一个环节的判断逻辑就有少许差异了。这貌似只能通过元数据实现。

2、InstanceOwner,网上实在找不到更多关于它的介绍,目前可知是用于多宿主环境下,宿主对wf实例的lock。没找到给实例赋值InstanceOwner的直接途径,网上找到的基本上是下面两行代码:

InstanceView view = instore.Execute(instore.CreateInstanceHandle(), new CreateWorkflowOwnerCommand(), TimeSpan.FromSeconds(30));
instore.DefaultInstanceOwner = view.InstanceOwner;

不知是基于什么因素考虑,总是觉得不太理解是什么意思,为什么要以及以这种方式设置DefaultInstanceOwner,如果不设置的话,那么下面这行代码运行时就会报错:

WorkflowApplicationInstance instance = WorkflowApplication.GetInstance(Guid.Parse(flowinstance.InstanceID), instore);

框架应该完全可以在底层就自动给我们处理InstanceOwner相关的东东,比如下面这句在没设置DefaultInstanceOwner的时候就不会报错:

wfApp.Load(Guid.Parse(flowinstance.InstanceID));

如何能设置自己的InstanceOwner呢,maybe可以通过InstanceOwnerMetadata。

 

CreateWorkflowOwnerCommand createCommand = new CreateWorkflowOwnerCommand()
{InstanceOwnerMetadata ={{ WorkflowHostTypeName, new InstanceValue(WFInstanceScopeName) },}
};

 

不过设置完了,怎么获取又是一个问题,有兴趣的朋友可以研究下这个文件,也可以在官方WF_WCF_示例里找到。总之持久化这趟子水够深。

 

其它参考资料:

Loading persisted workflow instances with WorkflowApplication

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/439148.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SharePoint Desiger编辑模板时提示“服务器错误,拒绝访问”的解决之道

这篇文件已被微软收藏。http://technet.microsoft.com/zh-cn/ff683721.aspx各位同志好,很多同志都用过SharePoint designer来编辑模板。经常出现“服务器错误,拒绝访问”。场景描述:我们办公电脑是XP系统。XP系统我们是用自己的域用户名密码登…

CCIE理论-第六篇-SD-WAN网络(一)

** CCIE理论-第六篇-SD-WAN网络 ** 1.SD-WAN介绍 1.什么是SD-WAN SD-WAN Software Defined 软件定义WANWide Area Network 广域网外网通俗的说企业网关可以慢慢的代替传统组网(大趋势)主要作用,省钱,简单,智能.易管理 传统方式 -Internet专线 (固定IP上下行带宽对等) -PPPOE …

【转】TFS测试管理

微软2010年发布的Visual Studio 2010或Visual Studio Test Professional 2010包含一个称为 Microsoft 测试管理器的新应用程序,用于帮助您使用测试计划来定义和管理测试工作。 Microsoft 测试管理器通过Team Foundation Server 集成,使您可以方便地进行测…

CCNA-网络常用工具介绍篇

链接:https://pan.baidu.com/s/1Mo3B9LR6YF4YfzSkMwn5OA 提取码:7dc7 这是免费提供滴工具,虽然其实都能用到,不过也就发发了. 第一个呢是EVE,是基于VM下的,就是模拟器来的.里面有ova直接拉进去vm里面开机就可以使用了.前面好像也发过 第二个是ENSP,是华…

敏捷项目管理过程改进

一、为什么敏捷? 目前大环境智慧城市、人工智能、大数据,面向To B的业务等,在要求产品管理需要快速的需求响应,项目管理需要更强的整合协调。复杂的大环境,就在推动我们用最敏捷的方式迎接这个多变的市场。 二、传统和…

CCNA-第六篇-静态路由+动态路由开头

** CCNA-第六篇-静态路由动态路由 ** 一,路由概念 什么是路由? 路由呢,应该说是除了IP以外在网络世界中最重要的东西了 万物互联,互联网,都是基于路由的,前期的啥静态动态,后期的MPLS,包括看到的VPN,虚拟专线等.都是基于路由的,就是像建房子那样,你最得把地基打好才能做其…

【转】敏捷开发,你真的做对了吗?

缘起 2017年3月,应移动事业群智能营销平台项目管理部负责人邀请,我开始支持智能营销平台CRM团队。智能营销平台是阿里文娱广告团队,是阿里巴巴淘外变现的主力军。CRM团队负责开发和维护CRM系统。CRM系统服务于销售和代理商,串起商…

CCNA-第七篇-思科私有路由协议-EIGRP-初级

CCNA-第七篇-思科私有路由协议-EIGRP 首先呢这个EIGRP之前呢, 路由协议是分几种的 一个叫距离向量协议RIP,IGRP(都过时了) 一个觉链路状态协议OSPF,IS-IS这些 还有个叫混合型的EIGRP 但是呢,这些只是书本上的定义,实际上没人会跟你说这个东东 这个怎么区分呢? 第一个呢,只传递…

CCNA-第八篇-OSPF-上

CCNA-第八篇-OSPF OSPF,最常用的路由协议,他来了他来了 OSPF呢怎么说呢 是一个比较重要而且比较基础的点,出到去外面要是说不会OSPF,那还算啥网络工程师 但是呢,他也不是那么的完全重要.因为很多小地方压根就用不到.但是列你不能不会呀 到了OSPF呢,配置就会逐渐的多那么一点点…

CCNA-第九篇-OSPF下+VLAN开篇初介绍

CCNA-第九篇-OSPF下VLAN开篇初介绍 补充一下官网的PPT对于DR/BDR的描述 邻居-drothers 和drothers之间的关系–2WAY 彼此之间只会交换hello包来让邻居正常通信,不交换LSA 邻接-dr/bdr/drothers的关系,-FULL 交换hello包与LSA信息 224.0.0.5-公用 224.0.0.6-仅有DR/BDR监听 其…

CCNA-第十篇-VLAN-下

CCNA-第十篇-VLAN-下 讲真,这个技术点没啥好讲的,很好理解.也很基础 通俗的说就是一个框框. . 其实理论上来说呢,CCNA是应该先教交换的再到路由的,哈哈,不过倒过来了,倒就倒吧.这里开始讲交换技术 LAN-内网 WAN-外网 VLAN虚拟局域网(一般用于内网) 交换机可以转发广播数据…

Office Web Apps安装部署(一)

系统要求为Windows Server 2012, 注意:安装Office Web Apps的服务器除了Office Web Apps之外,不能安装其他应用。包括不能安装Office,lync,,sharepoint等应用,即要单独部署。 安装IIS 7.0 打开服务器管理…

CCNA-第十一篇-VTP+STP(上)

CCNA-第十一篇-VTPSTP(上) VTP:VLAN中继协议(VLAN Trunking protocol )利用第2层中继帧,在一组交换机之间进行VLAN通信 STP:生成树,交换机的冗余协议 MSTP:多实例生成树,STP的进化版本. 然后先说说上次接口 思科有2种,华为有3种 access,t…

Office Web Apps安装部署(二)

SharePoint 2013调用Office Web Apps 注意:调用OfficeWebApps的sharepoint应用的身份认证必须是基于声明的身份认证(claims-based authentication) 首先安装好SharePoint2013,我在此部署文档中使用的是免费的sharepiont foundat…

CCNA-第十二篇-STP+ACL(下)

CCNA-第十二篇-STPACL(下) 首先说说要跳跳了 立个小FLAG, 两个月内急速完成CCIE理论LAB实操 因为接了个工作,主要我能做到就能做这份工作. 其实NP中间的点很多都会,只是因为笔记弄不急了, 就放到CSDN上重新复习学习一次. 下几篇开始就要起飞到CCIE了 后面还有个NAT还有一点SDN…

CCNA-第十三篇-NAT-上

CCNA-第十三篇-NAT-上 NAT- netword address translation 网络地址转换 NAT不仅仅是用于共享地址上网,NAT是一个很大的东西 核心思想是转换地址,以及端口号 NAT也分静态和动态 TAG:NAT很多时候也叫做端口映射,只是一个叫法而已 不只是设备,电脑本身也有端口号的哦! 电脑查…

entity framework6 edmx文件详解

entity framework中的edmx文件作为代码与数据库沟通的桥梁,作用是至关重要的。如果edmx文件出了问题,ef就基本上没得用了。虽然edmx文件是由ef自动生成的,但是一些特定的操作可能会引发ef的bug,从而导致edmx文件出错,并…

CCNA-第十四篇-NAT-下+链路聚合(LACP)+DHCP

CCNA-第十四篇-NAT-下 这一篇是是针对一下华为设备的nat,然后讲讲链路聚合 下一篇来一个DHCP一点点的SDN的介绍 **然后讲完SDN就基本上CCNA结束了哦**华为的链路聚合叫Eth-trunk 思科的链路聚合叫Ether-Channel 华为静态NAT 环境如下 首先把他的telnet开起来,server也是…

[Sharepoint2007对象模型]第一回:服务器场(SPFarm)

Sharepoint是微软一个很重要的服务器产品,它可以方便的创建和维护一个网站,在Sharepoint的管理中心提供了很强大的管理工具。同时为了更加灵活的后期定制和开发,Sharepoint提供了完整的对象模型,对象模型也就相当于Sharepoint的二…

CCNA-第十五篇-DHCP配置+SDN介绍(最后一章)

CCNA-第十五篇-DHCP配置SDN介绍 各位好,如果有一直看下来的谢谢支持 这里是CCNA的最后一篇了,如果真的能吸收很多内容,那么普通的东西基本上都没什么大问题了.除非就是工作经验 下一篇就到一个CCNA的综合实验了 DHCP 思科 创造一个dhcp地址池名字为dhcp 宣告网段为192.168…