工作流
根据 WfMC 的定义,工作流(WorkFlow)就是自动运作的业务过程部分或整体,表现为参与者对文件、信息或任务按照规程采取行动,并令其在参与者之间传递。官方的总是很抽象,抽象是为了能够体现各种情况,更加严谨可客观。可以这样理解这个工作流,在现实工作中办公室审批文档的流程。
传统方式:李四申报项目,找王二麻子经理审批完成,接着赵六副总签字,又跑到顶层张三董事画押。
而工作流的操作就是将这样一个流程完全的自动化、电子化,省去了李四到处跑这样一个流程。
简单地说,工作流就是一系列相互衔接、自动进行的业务活动或任务。我们可以将整个业务过程看作是一条河,其中流过的就是工作流。
解决了什么问题:
复杂的业务处理流程
繁琐的工作流程和大量的人工的手动交流表单
对于业务经常变化的业务,尽可能的利用变化的维度情况下调用不同的工作流来针对的处理
将人从传统的手动填写表单的效率低下中解脱出来;
在哪里用?
在什么样的业务中,可以使用到这样一个流程呢?其实如果理解之上的概念,在哪里使用也就知道了。
关键业务流程:订单、报价处理、采购处理、合同审核、客户电话处理、供应链管理等
行政管理类:各种申请类项目,出差申请、加班申请、请假申请、用车申请、各种办公用品申请、购买申请、日报周报等凡是原来手工流转处理的行政表单。
人事管理类: 员工培训安排、绩效考评、职位变动处理、员工档案信息管理等。
财务相关类: 付款请求、应收款处理、日常报销处理、出差报销、预算和计划申请等。
客户服务类: 客户信息管理、售后服务管理等管理等。
总的可以发现在之上业务中总会有这样一个流动的文件或者信息结构一致的信息流,根据权限不一经过各个参与者来完成一个业务的流程都是可以适用这样一个工作流的。
如何使用?
配置环境:vs 2020 .net 4.0 windows 8.1
一般流程
配置工作流-配置权限-激活工作流
1.新建工作流项目或者新建工作流xaml
a.新建工作流项目
新建好相应的项目后,出现一个program.cs 宿主程序、xaml配置好的工作流。
b.新建工作流
与上不同的是,没有宿主程序文件。直接添加了相应的工作流即可。
在原有的项目基础上,直接右键添加新项,活动即可。如图
2.添加活动
Vs2010需要添加或活动的.cs文件,并重新生成,这时候就可以在左边的工具栏内将这个生成好的活动以标签的形式添加到序列图中去。这时候在左边相应的工具栏这里看到生成好的活动图标了
3.绘制活动图
左边众多的工作流,以及自定义的活动配合绘制活动图即可。
实质上还是规定了一系列方法执行的步骤,按照可视化的方式呈现出来。而调用则是在程序声明这个工作流对象,然后把工作交给对应的工作流去就可以了。
实例demo verifyUser
绘制的活动图
如图,绘制了验证用户名和密码的过程,本例只是演示工作流,没有结合相应的业务逻辑。
配置好全局参数enUser
verifyUuser
public sealed class VerifyUser : CodeActivity { // 定义一个字符串类型的活动输入参数 public InArgument<UserEntity.user> ToUser{ get; set; } public OutArgument<UserEntity.user> OutUser{set;get;} // 如果活动返回值,则从 CodeActivity<TResult> // 派生并从 Execute 方法返回该值。 protected override void Execute(CodeActivityContext context) { user enUser = new user(); // 获取用户名 enUser.UserName = ToUser.Get(context).UserName; //输出参数 enUser.InstanceID = context.WorkflowInstanceId; context.SetValue(OutUser, enUser); }
名一直,否则则会报错。
verfiyPWD
// 定义一个字符串类型的活动输入参数 public InArgument<UserEntity.user> ToUser { get; set; } // 如果活动返回值,则从 CodeActivity<TResult> // 派生并从 Execute 方法返回该值。 protected override void Execute(CodeActivityContext context) { user enUser = new user(); // 获取pwd enUser.UserName = ToUser.Get(context).UserPWD; enUser.UserPWD = ToUser.Get(context).UserPWD; }
这里只需要传入参数即可,故无需传出参数。
宿主程序
/// <summary> /// 创建并启动工作流-2014年8月23日20:54:11 /// </summary> /// <param name="Request">相关参数</param> /// <returns>返回工作流对应ID</returns> public static Guid CreateAndRun(user Request) { //键值对的泛型集合,用来传入参数 IDictionary<string, object> input = new Dictionary<string, object> { { "Request" , Request } }; //为工作流的单个实例提供宿主,也就是建立好的工作流,可选传入参数 WorkflowApplication application = new WorkflowApplication(new VerifyWF(), input); //application.InstanceStore = instanceStore; //将当前工作流设置为闲置 application.PersistableIdle = (e) => { //将当前工作流终止, instanceUnloaded.Set(); return PersistableIdleAction.Unload; }; application.Unloaded = (e) => { instanceUnloaded.Set(); }; //出现异常时会调用该方法 application.OnUnhandledException = (ex) => { Console.Write("Exception"); return UnhandledExceptionAction.Terminate; }; Guid id = application.Id; //启动当前工作流 application.Run(); //中止当前工作流 instanceUnloaded.WaitOne(); return id; }
这里就是工作流委身的宿主程序,进入工作流也是通过这个程序来调用的。类似在java中的main。
本例没有中断工作流,故无需持久化到数据库。
效果
文件下载:http://pan.baidu.com/s/1jGJuYYa
结语
工作流解决了这样一个传统手动表单传递的这样一个过程,当然如果需要中断时处理还需要结合持久化数据库。这里的例子,仅限简单了解工作流这样一个过程。从程序内传参,到工作流处理。类似于委托,将这样一个方法委托给相应的工作流,工作流根据规定好的步骤来处理其中的参数和数据。又有点类似模板方法,定义好了算法的流程然后具体就自己来重写每个活动的excute方法即可。也相当于流程的处理和实现的解耦,突然觉得还是挺不错。
再说说我在研究这样一个新的技术的感悟,确实很困惑,特别是相关资料不是太多的情况下。研究了两天,了解了当中仅限基础中的基础。