WF活动(Activity)

本文详细介绍了WF中的各种活动,包括IFElseActivity、WhileActivity等基本活动,以及ConditionedActivityGroup、InvokeWorkflowActivity等高级活动。此外,还介绍了如何通过本地服务实现实现宿主和工作流之间的交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、WF活动概述:WF活动的顶层类的关系:

活动条件类型:

代码条件:

规则条件:关联.rules文件。

二、简单概述WF的基本活动:

IFElseActivity活动:在工作流中做一些分支决定。每个分支用一个IfElseBranchActivity表示。

WhileActivity活动:当需要重复执行子活动,直到条件满足进行退出时,可以使用WhileActivity活动

ParalleActivity活动:可以包含两个或多个SequenceActivity活动,也只有sequenceActivity活动才可以成为ParallelActivity的子活动。他并不是同时执行多个分支,每个工作流实例执行在单一的线程上,因此并行执行多个活动部可能。并不能保证sequenceActivity执行活动的顺序。

使用ReplicatorActivity活动:可以模拟C#Foreach语句,改活动创建和执行单一活动的多个备份。ReplicatorActivity中的子活动被认为是一个被创建的子活动实例的一个模板。在ActivityInitialChildData属性内,被传递一个种子的数据集合来处理。InitialChildData的属性是一个IList的集合。当ReplicatorActivity执行时,会对位于InitialChildData活动中的每个元素从活动模板中克隆并执行。ReplicatorActivity支持不同模式的操作,可以设置ExecutionType属性来进行设置,分别是SequentialParallel,指示复制子活动的实例是以并行方式还是顺序方式执行。

public sealed partial class Workflow1: SequentialWorkflowActivity { public Workflow1() { InitializeComponent(); childData.Add("这是数据1"); childData.Add("这是数据2"); childData.Add("这是数据3"); childData.Add("这是数据4"); } //定义用于种子数据的字符串变量 private List<string> childData = new List<string>(); public List<string> ChildData { get { return childData; } } private void Code_ExecuteCode(object sender, EventArgs e) { Object data = String.Empty; if (sender is Activity) { //如果当前活动的父活动为ReplicatorActivity if (((Activity)sender).Parent is ReplicatorActivity) { //获取ReplicatorActivity的引用 ReplicatorActivity rep = ((Activity)sender).Parent as ReplicatorActivity; //获取当前子活动的所需要显示的字符串数据,CurrentIndex表示当前活动的索引 data = rep.InitialChildData[rep.CurrentIndex]; } } Console.WriteLine("当前代码活动的实例数据是: {0}", data); } }

使用ConditionedActivityGroup活动是一个组合活动,允许构建相对复制的工作流。该活动实际上具有一些ParallelActivitywhileActivity行为,属于一种混合活动类型。接受一个或多个希望执行的子活动。子活动从左向右执行,将只有一个子活动被执行。每个子活动定义一个WhenCondition条件,决定活动是否应该被执行。如果定义了子活动的结果为True,则下一次序改子活动被执行一次,并且子活动持续执行直到WhenCondition的值为false。如果子活动的WhenCondition没有被定义,则子活动仅执行一次。

使用InvokeWorkflowActivity活动允许当前工作流执行一个新的工作流作为其步骤。InvokeWorkflowActivity要求工作流运行时使用当前附加到该运行时的计划程序创建新的工作流。所调用的工作流只能接受输入参数。不支持工作流完成后获取输出参数。

使用TerminateActivity活动和SubspendActivity活动:TeminiateActivity被用于声明性的终止当前工作流,当工作流终止时,触发WorkflowTerminated事件。SubspendActivity活动,挂起当前工作流,此时WorkflowSuspended事件被触发。

二、本地服务和事件驱动的活动:WF中的服务可分为核心服务和本地服务。核心服务由WF定义,而本地服务由开发人员定义。本地服务大都用于工作流和宿主之间进行通信。

工作流主要在以下方面和本地服务进行交互:

调用本地服务的一个方法;

等待本地服务引发一个事件;

步骤:定义一个服务契约;为接口应用ExternalDataExchangeAttribute特性;定义继承接口的类;创建一个服务实现类的实例,并添加到工作流运行时引擎,

使用本地服务在宿主和工作流之间通信:以投票为例来演示。这次将会弹出一个确认框来让用户选择,根据选择继续工作流。

首先考虑宿主传递一个用户的别名到工作流中。当工作流提示用户投票时,需要这个别名。为了在宿主和工作流之间传递参数。定义一个ExternalDataEventArgs派生参数类:代码:

//定义在宿主和工作流之间需要传递的参数 [Serializable] internal class VotingServiceEventArgs : ExternalDataEventArgs { private string aliasValue; public VotingServiceEventArgs(Guid instanceID, string alias) : base(instanceID) { this.aliasValue = alias; } //公共属性,用于在宿主和工作流实例之间传递参数,这可以是复杂的类或者是简单的字符串 public string Alias { get { return this.aliasValue; } } }

然后工作流需要知道用户选择了什么,需要定义两个事件,让工作流触发外部事件,当批核后,触发批核事件,批核工作流得以执行。反之执行拒绝工作流。

// 定义契约,用于联系本地服务和工作流 [ExternalDataExchange] internal interface IVotingService { event EventHandler<VotingServiceEventArgs> ApprovedProposal; event EventHandler<VotingServiceEventArgs> RejectedProposal; //创建一次新的投票 void CreateBallot(string alias); }

ApprovedProposalRejectProposal类似于两个信号,通知工作流执行,工作流将使用HandleExternalEventActivity来处理外部事件。

定义类实现接口:

//在宿主端实现服务契约,实现其方法和事件以便工作流内部调用 internal class VotingServiceImpl : IVotingService { public event EventHandler<VotingServiceEventArgs> ApprovedProposal; public event EventHandler<VotingServiceEventArgs> RejectedProposal; //由工作流调用来开启新一次的投票,该方法将在宿主线程中显示一个投票对话框。 public void CreateBallot(string alias) { Console.WriteLine("为{0}创建投票", alias); ShowVotingDialog(new VotingServiceEventArgs(WorkflowEnvironment.WorkflowInstanceId, alias)); } //显示消息框,并触发事件 public void ShowVotingDialog(VotingServiceEventArgs votingEventArgs) { DialogResult result; string alias = votingEventArgs.Alias; //向用户显示一个对话框,根据用户的响应触发不同的事件 result = MessageBox.Show(string.Format("是否批核 , {0}?", alias), string.Format("{0} 投票", alias), MessageBoxButtons.YesNo); if (result == DialogResult.Yes) { EventHandler<VotingServiceEventArgs> approvedProposal = this.ApprovedProposal; if (approvedProposal != null) approvedProposal(null, votingEventArgs); } else { EventHandler<VotingServiceEventArgs> rejectedProposal = this.RejectedProposal; if (rejectedProposal != null) rejectedProposal(null, votingEventArgs); } } }

工作流设计:添加一个CallExternalMothodActivity来调用CreateBallot方法;添加一个ListenActivity,等待多个事件中的任何一个事件发生。在该活动中

添加2HandleExternalEventActivity,分别监听ApprovedProposalRejectProposal

当工作流批核或拒绝后,同时响应两个活动的Invoked事件。

//当拒绝事件触发后,触发此事件 private void OnRejected(object sender, ExternalDataEventArgs e) { Console.WriteLine("提议由{0}拒绝.", this.alias); } //当批核事件触发后,触发此事件 private void OnApproved(object sender, ExternalDataEventArgs e) { Console.WriteLine("提议由{0}批核.", this.alias); }

最后注册服务。

事件驱动活动简介:一些活动是组合活动,这种类型的活动作为其他事件处理活动的容器,比如EventDrivenActivityListenActivity 使用EventHandlingScopeActivity活动:定义一个完全不同事件的处理活动,它具有2个分离的区域:主要子活动和一套事件处理活动。除了子活动,事件处理活动被包含在一个或多个EventHandlersActivity内部,作为EventHandlingScopeActivity的子活动。EventHandlingScopeActivity会将其主子活动与EventHandlersActivity活动并行执行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值