Activity学习研究.docx
- 文档编号:23462988
- 上传时间:2023-05-17
- 格式:DOCX
- 页数:59
- 大小:1,022.57KB
Activity学习研究.docx
《Activity学习研究.docx》由会员分享,可在线阅读,更多相关《Activity学习研究.docx(59页珍藏版)》请在冰豆网上搜索。
Activity学习研究
微软工作流活动研究
微软工作流中提供了28个活动
活动名称:
Code
类名称:
CodeActivity
说明:
是一个可以添写代码的结点,是一个最基本的结点
CodeActivity提供了一个ExecuteCode事件,可绑定一个codeActivity1_ExecuteCode(objectsender,EventArgse)格式的方法,每当流程运行到该结点时行绑定到该事件的方法
在设计模式中双击CodeActivity,可自动完成ExecuteCode事件的绑定,并体现到ExecuteCode属性上
该事件所绑定的方法的格式如下:
privatevoidcodeActivity1_ExecuteCode(objectsender,EventArgse)
{
}
示例代码:
1.新建工作流项目
2.然后再拉一个Code活动图标到工作流界面设计器上
3.再双示CodeActivity1,会出如下方法
4.然后就可以在方法CodeActivity1_Executecode方法中加入你要执行的代码.
privatevoidcodeActivity1_ExecuteCode(objectsender,EventArgse)
{
Console.WriteLine("HelloWorld!
!
!
!
");
Console.Read();
}
5.然后再运行出现:
HelloWorld!
!
!
就OK,下面是示例工程代码.
一、活动名称:
IfElse
类名称:
IfElseActivity条件分支活动
说明:
使您的工作流能够有条件地执行多个可供选择的分支之一。
可在每个分支上放置一个条件,而条件为真的第一个分支将执行。
无需在最后一个分支上放置条件,因为它被视为“else”分支
IfElseActivity包含一个或多个子活动,每个子活动将一个布尔表达式绑定到一系列活动,当且仅当该布尔表达式值为true时执行这些活动。
.IfElseActivity有两个IfElseBranch子控件,分别作为IfElse的两个分支容器,系统自动添加,
.其中左边(为真件条)的IfElseBranch容器要设Condition
.IfElse左边(为真件条)的IfElseBranch容器的Condition有两个条件模式:
CodeCondition,DeclarativeRuleCondition
示例代码:
1.新建工程项目如下图:
2.然后再拉一个IfElse活动图标到工作流界面设计器上
3.再设置其IfElse的规则,设置ifElseBranch1的规则条件,如下图
点击ConditionName后,可以选择按钮会出现如下图
4.ifElseBranch2就不用设置了,如果ifElseBranch1的条件不满足就执行ifElseBranch2
5.因为是条件分支,所以外面就传入一个值以供条件分支判断,要加入如下代码,
Dictionary
parameters.Add("OrderValue",9000);
WorkflowInstanceworkflow=workflowRuntime.CreateWorkflow(type,parameters);
将条件传入工作流中,然后由工作流中设置好的条件进行判断,再返回结果。
6.工程代码如下:
二、活动名称:
Listen
类名称:
ListenActivity工作流侦听活动
说明:
使工作流能够等待(可能存在的)多个事件之一,或者在指定的超时间隔之后停止等待,并且基于结果分支。
可向每个分支中添加一个或多个由事件驱动的活动。
只有第一个满足条件的分支被执行;其他分支都不会运行。
当人为因素与宿主应用程序进行交互并执行一些操作来唤醒工作流时,本地服务将向运行时发布请求来恢复钝化的工作流。
WindowsWorkflowFoundation工具箱包含一个称为Listen的活动,该活动只是使工作流空闲并侦听传入的唤醒呼叫
单线触发容器,使用EventDrivenActivity作为分支容器,当某条分支中的结点执行完成后,该ListenActivity结点就结束,继续向下执行,其他分支内的结点就不执行了
.
示例代码:
1.新建工程项目。
2.然后再拉一个Listen活动图标到工作流界面设计器上,如下图
3.POSatusListen中三个事件OnOrderApprovedEventDriven、OnTimeoutEventDriven、OnOrderRejectedEventDriven要等待用户的干预.
4.下面这段代码就是模拟用户的干预,代码如下:
staticvoidOnWorkflowIdled(objectsender,WorkflowEventArgse)
{
orderService.instanceId=e.WorkflowInstance;
RandomrandGen=newRandom();
intpick=randGen.Next(1,100)%3;
switch(pick)
{
case0:
orderService.ApproveOrder();
break;
case1:
orderService.RejectOrder();
break;
case2:
//timeout
break;
}}
6.示例代码如下:
三、活动名称:
invokewebservice和InvokeWorkflow
四、类名称:
invokewebservice和InvokeWorkflow
说明:
(invokewebservice)使您的工作流能够调用Web服务方法。
您需要指定要使用的代理类(使用WSDL),以及您想要调用的方法的名称。
同步和异步调用都受到支持。
(InvokeWorkflow)使您的工作流能够调用或启动另一个工作流(可达到任意深度)。
例如,被调用的工作流可以调用第三个工作流,该工作流又可以调用第四个工作流,等等。
递归调用不受支持。
受支持的调用模型是发后不理。
示例代码:
1.首先要创建工作流的工程,如下图
2.WebServicePublish是webservice要进行发布,发布以后就会产生WebServicePublishWorkflow_WebService.asmx所在项目,WebServicePublish中间要进行如下设置
选中WebServieReceive后点出属性窗口如下图
中间Path中的PurchaseOrderID是接收的值.
3.WebServiceInvokeWorkflow工作流界面如下图,在其中放入了invokeWebService和code活动组件,如下图
选择中invokeWebService,然后点击属性窗口,如下图
中间的Path中的PurchaseOrderId是要传值给webservice的.
工程代码如下:
五、活动名称:
FaultHandler
类名称:
FaultHandlerActivity
说明:
FaultHandlerActivity异常捕获活动,错误处理是由FaultHandlerActivity活动来完成的。
每个FaultHandlerActivity活动都与一个.net异常类型相关联,并且它包含一系列的活动,如果错误类型与某个FaultHandlerActivity关联的错误类型匹配的话,就会执行为个FaultHandlerActivity活动。
一个FaultHandlersActivity活动包含0-n个FaultHandlersActivity子活动,FaultHandlersActivity可以是任何复合活动的子活动。
WF中的错误处理通常被视为一个反向的工作,因为它的目标是当异常发生时,撤销活动中不成功的部分的工作。
FaultHandlerActivity的执行完成不能被认为是事务活动的成功完成。
事务活动会先被设置成错误状态,然后是关闭状态。
任何兄弟活动同样会被取消。
同时,compensation也会成为不可用状态。
.一个faultHandlersActivity容器内可以添加多个faultHandlerActivity
.每个faultHandlerActivity的FaultTyp属性绑定到一个特定的System.Exception派生类
每个faultHandlerActivity都有一个对应的子容器,在该容器内可以添加其他功能类Activity控件
.当结点产生异常后,如果该异常类型在faultHandlersActivity容器内有相应的faultHandlerActivity绑定,就会执行该faultHandlerActivity对应的子容器中的内容
当使用FaultHandlers容器捕获常后,会执行用FaultHandlers容器中对应faultHandlerActivity子容器的内容,同时该异常不会触发引擎的OnWorkflowTerminated事件,但会被跟踪监视到
示例代码:
1.创建工程界面如下图:
2.在工作流设计器上加入一个Code活动如下图
3.然后点击图标
就会出如下界面
5.然后再选择中中间的那个图标会出现如下图,进行设计属性
6.其中CodeActivity1是错误发生捕获后要处理的代码
示例工程代码如下:
六、活动名称:
ConditionedActivityGroup(CAG)
类名称:
ConditionedActivityGroup(CAG)
说明:
使您的工作流能够基于特定于每个活动的准则有条件地执行一组子活动,直到针对CAG整体满足完成条件。
子活动相互独立并可能并行执行。
示例代码:
1.创建工程界面如下:
2.在工作设计器中加入ConditionedActivityGroup(CAG)活动后,然后再在ConditionedActivityGroup(CAG)活动中加入Code活动,如下图界面
2.当中间的两个code活动全部执行完毕后,ConditionedActivityGroup(CAG)活动才会执行完成.
3.工程代码如下:
七、活动名称:
Compensation和CompensatableSequence
类名称:
Compensation(补偿活动)
说明:
使您能够在发生错误时调用代码来撤消或者补偿已经由工作流执行的操作。
通常,对于现在已被取消的操作,您可能希望向先前已经获得成功通知的用户发送电子邮件。
WF中对于已完成事务的补偿模式,是对工作流中出现的异常进行处理的过程,并且会在逻辑上撤销已完成的事务。
WF补偿有以下两种形式:
当异常没有被处理的时候,系统隐式的补偿;
使用Compensate活动进行显式的补偿。
示例代码:
1.创建工程项目(略)
2.在工作流设计器中加入活动后如下图
3.其中点击图中所示
点击后就会出现如下图,即为事件失败后的补尝动作
其中Refund就是补尝的一个Code活动。
3.然后再点击界面下方的
这个图标后会出现错误捕获活动,如下图所示
4.然后选择中CompensateRefund后点击属性窗口,出现如下图
其中TargetActivityName中就是要补尝那个活动.
4.下面就是示例代码工程
八、活动名称:
CallExternalMethod和HandleExternalActivity和eventDriven
类名称:
CallExternalMethod和HandleExternalActivity和eventDriven
说明:
(CallExternalMethod)在工作流内部调用外部方法和(HandleExternalActivity)绑定外部事件(指工作流内部事件在宿主中触发)
(eventDriven)代表一系列其执行由事件触发的活动。
第一个子活动必须能够等待外部事件。
可行的首要子活动是EventSink和Delay。
在这种情况下,Delay用作超时。
一个容器,该容器内的第一个结点必需是可以进入idle状态的结点,如Delay或HandExternalEvent
示例代码:
1.创建工程
2.创建工作流如下图所示
4.此实例通过一个ifelse活动来判断,如果输入的金额大于1000或小于1000都会跑相应的设定的事件活动,中间invokeGetLeadApproved和InvokeGetManagerApproved是CallExternalMethod活动,下面通过一个Listten活动来监控外部传来的参数再进行相应的活动,中间ApproveEvent和rejectEvent是HandleExternalActivity活动
5.下面是一些设置点(CallExternalMethod):
●InterfaceType要绑定到标记为[System.Workflow.Activities.ExternalDataExchange()]的一个接口上
●MethodName要绑定到该接口声明的一个方法
●引擎中要加载ExternalDataExchange服务
●ExternalDataExchange服务,要加载实现[1]所绑定接口类的实例
●运行到CallExternalMethodActivity结点后自动调用实例中的方法。
用参数映射中的设定传参,得到返回值
6.下面是一些设置点(HandleExternalEventActivity):
Ø.InterfaceType要绑定到标记为[System.Workflow.Activities.ExternalDataExchange()]的一个接口上
Ø.EventName要绑定到该接口声明的一个事件,事件格式最好与Invoked的事件签名一至
(objectsender,ExternalDataEventArgse)
e参数可以通过重写ExternalDataEventArgs类进行括充,下例就重写了
(事件用的是2.0的写法,也可以使用传统写法)
Ø.引擎中要加载ExternalDataExchange服务
Ø.ExternalDataExchange服务,要加载实现[1]所绑定接口类的实例
Ø只有当宿主中触发绑定的事件后才会继续向下运行。
Ø下例中如果所传的“InstanceId”与当前实例的[InstanceId]不一至时会报错
Ø触发事件时的两个参数值会传入HandleExternalEventActivity的Invoked事件对应的参数,也会赋给参数映射中的设定
Ø触发事件时对象.触发事件("发送对象",当前操作的实例.InstanceId)将要触发该事件的工作流实例的GUID号传入是非常重要的,因为引擎中可能有多个实例在等待该事件,发送工作流实例的GUID号可以告诉引擎是要触发那一个实例事件
Ø在实例挂起或没到HandleExternalEventActivity结点时,也可以在外部触发事件,这时当实例运行到该结点时HandleExternalEventActivity就可直接过去,而不用再触发了
示例代码如下:
九、活动名称:
Delay
类名称:
DelayActivity
说明:
使您能够控制工作流的定时以及将延迟内置到工作流。
您可以在Delay活动上提供超时,以便工作流在恢复执行之前暂停
示例代码如下:
1.创建工程
2.创建工作流界面如下
3.中间设置属性如下图:
代码如下:
活动名称:
Parallel
类名称:
ParallelActivity
说明:
一个ParallelActivity可以包含2个以上的SequenceActivity子活动。
ParallelActivity中仅能包含SequenceActivity作为自己的子活动。
在同一时刻,ParallelActivity活动可以同时并行处理2个以上的SequenceActivity活动。
尽管SequenceActivity分支活动被安排在同一时刻进行处理,但是这些分支中的活动不会在同一时刻开始处理。
处理将从一个SequenceActivity分支所包含的一个活动开始,当一个活动结束后,则开始处理另一个SequenceActivity分支的活动,如此切换处理所有SequenceActivity分支中的所有活动。
在SequenceActivity分支切换过程中,ParallelActivity活动并不会严格保证执行的顺序。
如果SequenceActivity分支中包含了一个DelayActivity活动,那么整个运行并不会被阻止在该活动上,而是将运行另外一个分支中的活动。
虽然所有的SequenceActivity都是在同一时刻被处理,但是分支中的活动并不是真正意义上的并行处理。
WF运行时采用了单线程来处理每一个工作流的实例。
ParallelActivity活动中所有的分支将会共享同一个工作流实例的线程。
因此,在某一个时间片上只会有一个分支中的活动在运行。
示例代码:
1、新建一个顺序工作流控制台程序;
2、在工具箱中选中Parallel活动并将它拖到设计界面中;
3、在2个SequenceActivity中分别托放2个CodeActivity,界面如下
4、鼠标双击CodeActivity并填写运行代码,如下所示:
privatevoidcodeActivity1_ExecuteCode(objectsender,EventArgse)
{
Console.WriteLine("第一分支的第一个活动");
}
privatevoidcodeActivity2_ExecuteCode(objectsender,EventArgse)
{
Console.WriteLine("第一分支的第二个活动");
}
privatevoidcodeActivity3_ExecuteCode(objectsender,EventArgse)
{
Console.WriteLine("第二分支的第一个活动");
}
privatevoidcodeActivity4_ExecuteCode(objectsender,EventArgse)
{
Console.WriteLine("第二分支的第二个活动");
}
5、运行结果:
从结果中可以看出分支中的活动是交替往下运行的。
6、现在我将在第一个分支中加上一个DelayActivity(时间超时设定为5秒),看看运行结果会如何变化,重新设计后的工作流定义界面如下:
修改后的运行结果:
从上面的结果我们会发现由于第一个分支中存在DelayActivity,所以工作流实例将会运行第二分支中的活动,当第二分支中的第一个活动结束后应该会切换运行第一分支中的活动,但是由于DelayActivity设定为5秒,还处于阻塞状态,所以将切换运行第二分支中的活动。
7、下面我将在第二分支中也加上一个DelayActivity(时间超时设定为5秒),看看运行结果如何?
修改后的工作流定义界面如下:
修改的运行结果如下:
分析运行结果我们可以看出,由于第一分支的一开始被DelayActivity(5秒),所以工作流实例会运行第二分支中的第一个活动,然后切换到第一分支中,但是第一分支中还处于阻塞状态,所以切换到第二分支运行下面的活动,同样也被DelayActivity阻塞。
然而第一分支中的阻塞会比第二分支的阻塞提前结束,所以会运行第一分支中下面的CodeActivity。
活动:
Policy
类活动:
PolicyActivity
说明:
当您真正需要控制工作流的流动并连接各种工作块时,您应该使用IfElse活动组合。
但如果您所需要的仅仅是一个编程If语句序列,带有附加到分支的简单代码,那么最好使用Policy活动。
Policy活动是一个规则集合。
与各规则相关的代码仅限于设置工作流属性,调用工作流方法或针对引用的程序集中的类型的静态方法。
PolicyActivity封装了一个集成的的规则引擎,并且允许你在业务逻辑和应用中使用这些规则引擎。
一个Policy是代表你定义一组类似的"If-Then-Else"逻辑的规则并且将它组织在一个RuleSet中,然后你可以使用PolicyActivity来调用或执行这些规则引擎。
这些规则很大程度上使用的是CodeDom类型,所以不像WF的其他Activity,PolicyActivity很多时候不能直接使用(特别是不能在VS2005的工具箱),你需要从PolicyActivity继承并且创建一个自定义的Activity来使用PolicyActivity和这些规则。
一般使用上,
1.先定义一个从PolicyActivity继承来的自定义Activity
2.定义一些数据字段为这个Activity的属性
3.然为这个Activity定义一个System.Workflow.Activities.Rules.RuleSet,可以使用CodeDom定义一个或多个Rule,加入到这个RuleSet中。
一个Rule包括一个条件以及一个多多个Active,一般条件相当于上面说的IF,另外的Active则相当于Then和Else的场景。
最简单的方法,也可以使用RuleEditor来完成这些。
4.每个PolicyActivity都有一个RuleSetReference属性,定义完RuleSet之后,可在VS界面中设置该属性,代码方式下则需要将这个RuleSet封装到一个RuleDefinitions对象中,然后设置PolicyActivity的RuleDefinitions.RuleDefinitionsProperty为封装的RuleDefinitions对象
第一个问题是CodeDom和RuleSetEditor两种方式你更喜欢哪种。
如果不是做练习,那么我更喜欢RuleSetEditor的方式,因为Beta1的时候,没有RuleSetEditor(只有一个外置的小工具RuleSetEditor-2005-09-12.exe),而Beta2这个工具内置进来了。
你更多的时候是只能使用CodeDom,
第二,使用CodeDom的方式,会将Rule和你的PolicyActivity编译到一起成为一个二进制的格式,我不喜欢这种方式,使用RuleSetEditor会单独的生成一个后缀为.rules的XML文件,编译后和CodeDom的方式是一样的,我更喜欢这种分
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Activity 学习 研究
![提示](https://static.bdocx.com/images/bang_tan.gif)