Windows 工作流设计模式.docx
- 文档编号:26914618
- 上传时间:2023-06-24
- 格式:DOCX
- 页数:13
- 大小:146.40KB
Windows 工作流设计模式.docx
《Windows 工作流设计模式.docx》由会员分享,可在线阅读,更多相关《Windows 工作流设计模式.docx(13页珍藏版)》请在冰豆网上搜索。
Windows工作流设计模式
基础内容
Windows工作流设计模式
MatthewMilner
代码下载的MSDN代码库中可用
浏览在线代码
目录
执行工作的N数据项
侦听的超时
变体:
状态机
散点图收集
使用多个操作启动工作流服务
设计模式提供常用的、可重复的方法来完成软件开发任务,各种不同的模式将分别说明如何在代码中实现特定目标。
开发人员开始使用WindowsWorkflowFoundation(WF)时,他们通常会问的相关问题是:
如何使用此技术实现常见任务。
本月我将介绍几个在WF中使用的设计模式。
执行工作的N数据项
通常,工作流都不驱动完全由逻辑但还数据,(如组织中的用户的列表或订单,列表的一组工作流中的步骤需要执行一次的每个项目的。
尽管可能不是模式本身,该简单的、可重用的位逻辑的是其他模式我在本文中讨论的一个重要组件。
此方案的关键使用复制活动循环访问的数据的集合和集合中执行相同的每一项活动。
复制活动提供驱动器迭代事件初始化每个数据项和条件,您可以打破执行子活动的数据项目的集合属性。
实质上是,复制活动提供ForEach结合DoWhile样式条件执行语句的语义。
渚嬪的方式指定与属性类型列表<字符串>的工作流包含员工的电子邮件地址,可以循环访问列表和每个员工,如图1的中所示发送邮件。
图1复制与活动SendMail
鍦ㄨ繖绉嶆儏鍐典笅,复制活动必须InitialChildData属性绑定到一个集合实现IEnumerable接口包含用于电子邮件地址。
这些地址用于设置为每个迭代的收件人的地址。
通过处理ChildInitialized事件,您访问数据的项和执行动态活动实例。
图2显示如何从集合中的电子邮件地址传递给事件可用于设置RecipientAddress属性相关的电子邮件活动实例。
正在初始化子活动的图2
复制代码
publicList
{"matt@","msdnmag@"};
privatevoidInitChildSendMail(objectsender,ReplicatorChildEventArgse)
{
SendMailActivitysendMail=e.ActivityasSendMailActivity;
sendMail.RecipientAddress=e.InstanceData.ToString();
}
按顺序或者以并行方式,可以执行复制活动。
顺序方式复制等待每个迭代完成后才能开始新的迭代。
并行方式所有活动是初始化一次计划和执行与非常类似于并行活动,但每个分支中相同的定义。
能够循环访问数据的项调用以并行方式,某些操作,等待响应的每一项是很多包括本文中讨论的几个的设计模式中的关键。
侦听的超时
在侦听超时方案,必须等待某些输入但只在一定的时间要求。
渚嬪的方式您可能有通知使用电子邮件和需要等待但如果的答复,管理器管理器没有响应时间,在特定时间内您的工作流都应采取如发送提醒的进一步操作。
此模式的任何实现的核心是,Listen活动。
侦听活动允许工作流可暂停,同时等待许多不同的事件或输入。
此功能还可以完成与并行活动,但不同之处等待所有的事件的并行活动而侦听活动可响应第一个事件发生并停止侦听的所有其他事件时。
将此功能能够等待一个指定由该延迟活动的时间与组合在一起使工作流等待一个事件,但超时,如果不会发生该事件。
图3显示等待消息到达通过Windows通信基础(WCF)或超时过期的一个Listen活动。
请注意Listen活动可以有多个分支可以因此侦听对于很多不同的事件在同一时间。
图3可与多个分支侦听活动
此类实现使工作流等待一个特定的响应时间。
通常,在超时发生在工作流旨在采取相应的操作。
在超时发生后,展开管理器审核示例上,,经理应提醒她了她需要批准的未处理请求。
经理将提醒后,工作流需要还原到的响应超时时间,等待状态。
围绕一个侦听一个时活动使工作流继续等待直到满足某个条件。
侦听活动的分支内,继续等待或收到的需要响应后上移动适当操作条件。
在简单的情况下一个标志可用于管理导致While的该条件循环,直到设置了标志的活动。
因此时,管理器发送响应,标志可设置和While活动关闭,允许工作流将移动到下一个活动。
与延迟活动分支中,会发生延迟后,活动用于管理器发送提醒和确保仍将条件设置为强制While活动再次,安排子活动,如图4的中所示。
图4收听与在发送提醒
在此的示例停止等待该触发器条件是只需在的经理发一个响应,但是,如果当然,复杂计算的任何级别可以接收对输入数据。
一个选项是将一个规则集,活动策略以确定是否已将移动到下一步工作流中满足所有条件。
变体:
状态机
您开发而不是顺序工作流的状态机工作流时发生了一个变体超时模式与侦听。
在这种情况下状态活动代替侦听活动并为侦听多个事件,在同一的时间包括使用延迟活动。
处于给定的状态说,等待供审批,您可以建立模型作为同一方案之前,等待响应或超时。
的图5显示了示例工作流实现与之前相同的逻辑,但使用状态机工作流。
图5状态计算机侦听
它是实际易于管理以下条件,因为没有为时不需要活动。
而是,延迟时可以发送该提醒或执行其他操作,然后转换到当前的状态使用SetState活动这会导致延迟活动执行再次,重置超时。
如果接收到响应符合条件的继续,用于SetState活动将移动到下一状态。
这两个分支的图6所示。
图6侦听状态活动中
散点图收集
您需要启动许多子工作流进行某些工作,使用散点图收集模式。
这些工作流可能所有执行相同的工作上不同的数据或每个可能执行不同的工作。
目标是启动的所有工作,优化的多个线程来完成的任务更快地如果如有的可能使用每个任务完成后要收集结果,然后通知父工作流。
可以启动多个工作流,只需通过复制活动和InvokeWorkflow活动。
工作流启动异步,即所需内容但它会等待父工作流中更具挑战性因为您需要一个可以从子流接收数据的阻止活动。
使用接收活动,父工作流可以等待完成从和接收任何结果返回每个工作流启动的每个子活动。
的图7显示了父工作流中的此模式的高级视图。
图7复制与InvokeWorkflO和接收活动的
图使得此模式查看简单实现,但确保在子工作流可以正确回叫使用WCF父工作流所需的步骤的几个键。
需要从父工作流传递到每个要启用将数据发送回工作流实例标识符和以选择正确的接收活动会话标识符包括该父工作流子子上下文信息。
此外,父工作流必须寄宿作为WCF服务启用该的通信,但需要在开始使用WorkflowRuntime,如图8中所示。
作为WCF服务启动工作流必须寄宿的图8
复制代码
WorkflowServiceHosthost=newWorkflowServiceHost(typeof(MSDN.Workflows.
ParentWorkflow));
try
{
host.Open();
WorkflowRuntimeruntime=host.Description.Behaviors.
Find
WorkflowInstanceinstance=runtime.CreateWorkflow(
typeof(MSDN.Workflows.ParentWorkflow));
instance.Start();
Console.ReadLine();
}
catch(Exceptionex)
{
Console.WriteLine(ex);
Console.ReadLine();
}
finally
{
if(host!
=null&&host.State==CommunicationState.Opened)
host.Close();
else
host.Abort();
}
每个子工作流参数输入至少需要父工作流ID和接收活动ID的除了需要处理子工作流中的任何业务数据。
该工作流的参数定义为在工作流定义的公共属性。
InvokeWorkflow活动允许您将参数传递给子工作流,并提供属性对话框中的这些属性。
InvokeWorkflow活动上的参数绑定到属性或工作流中的一个域。
但是,用于调用多个工作流复制活动参数需进行每次调用都需要唯一的值,因为在代码中设置为每个的迭代的属性字段可以设置与当前的输入。
因此,InvokeWorkflow活动上的参数应该绑定到,工作流中的字段,并且重创建子工作流之前,将在代码中更新这些字段。
您的初始斜率可能将属性设置在ChildInitialized事件过程中执行复制程序,为我前面,显示SendMail的示例,这是一个很好的位置开始。
但是时执行复制活动,在并行模式下,所有子级之前都初始化开始执行的任何实例。
因此,如果设置该属性在ChildInitialized事件中时活动执行该InvokeWorkflow,活动的所有实例将都使用一组数据。
但是,ChildInitialized事件不会提供对活动实例和推动迭代的数据项的访问。
一种方法是收集的数据项,以便它在执行过程中可到正确的活动实例相关的唯一标识符存储它。
图9显示ChildInitialized事件处理程序复制活动的实例数据键上唯一的标识符,ActivityExecutionContext的字典中的存储位置。
图9在迭代过程中存储数据
复制代码
privatevoidInitChild(objectsender,ReplicatorChildEventArgse)
{
InvokeWorkflowActivitystartWF=
(InvokeWorkflowActivity)e.Activity.GetActivityByName("StartChild
Workflow");
InputValueCollection[(Guid)e.Activity.GetValue(
Activity.ActivityContextGuidProperty)]=e.InstanceData.ToString();
}
下一步中,初始化InvokeWorkflow活动,您使用调用事件来设置参数。
此时执行,在子工作流的输入所需的所有值都是可用的。
工作流标识符可以被检索,WorkflowEnvironment,从,并可以从上下文属性在接收活动的实例上检索会话标识符。
最后,业务数据可以在检索对当前执行上下文使用标识符。
图10显示初始化参数被传递到工作流代码。
图10初始化InvokeWorkflow活动
复制代码
privatevoidPrepChildParams(objectsender,EventArgse)
{
InvokeWorkflowActivitystartWf=senderasInvokeWorkflowActivity;
ReceiveActivityreceive=
(ReceiveActivity)startWf.Parent.GetActivityByName(
"ReceiveChildCompletion");
Contracts.ChildWFRequestrequest=newContracts.ChildWFRequest();
request.WFInstanceID=WorkflowEnvironment.WorkflowInstanceId.ToString();
request.ConversationID=receive.Context["conversationId"];
request.RequestValue=
InputValueCollection[(Guid)startWf.Parent.GetValue(
Activity.ActivityContextGuidProperty)];
StartWF_Input=request;
}
子工作流启动后,它就可以开始执行工作进行,并在完成时,使用发送活动通知父工作流。
在发送邮件前上下文必须将设置发送活动上,以确保邮件获取发送到正确的接收活动,父工作流中。
使用从父传递值,上下文正确使用可以设置该BeforeSend事件,如下所示。
复制代码
e.SendActivity.Context=newDictionary
{"instanceId",InputValues.WFInstanceID},
{"conversationId",InputValues.ConversationID}};
位置、父工作流启动,和活动循环访问数据的集合执行复制程序中的所有这些部分,启动的每个项目的一个子工作流并等待从每个并行的消息。
然后,如子流完成,将它们发送一条消息回父可以继续处理后,所有子工作流已报告都了返回的结果。
使用此方法,子流可以运行在同一时间都有其自己提供真正的异步处理的线程。
使用多个操作启动工作流服务
在很多的示例工作流服务启动与一个单个的接收活动建模单个操作中。
在情况下我此处讨论您需要使用多个方法调用中启动工作流服务。
也就是客户端应用程序可能不总是调用相同的操作开始您的工作流进行交互,您需要能够设计工作流,以便可以启动多个操作的基础上。
有实际两个不同种类的这种模式,根据您要如何后第一次请求处理的请求。
第一个选项是启用工作流以启动多个操作之一,然后该操作完毕后上移动的工作流处理,直到您定义另一个操作可以被调用的点。
为此目的,您需要返回到侦听活动,并将其用作您的工作流定义中第一个活动。
中然后,活动的每个分支中,添加一个接收活动、配置它用适当的服务的操作信息并绑定处理,任何必要参数,如图11中所示。
图11多侦听活动中接收活动
在关键步骤是确保侦听活动中的所有接收活动的都具有CanCreateInstance属性设置为True。
这将指示WCF运行时如果没有上下文信息请求,该值指示一个现有的工作流实例上的可用,它是可以启动新实例根据配置的操作。
尽管它可能看上去接收以外的其他活动创建工作流略有奇数,运行库创建实例,然后启动,只将WCF消息的内容发送到接收活动的尝试。
在这种情况下将启动工作流后则这两种接收活动的执行并可以等待输入。
我提到过有两个变体,此模式。
当您使用侦听活动与前面的示例中相同的一个操作启动工作流,但然后将侦听活动完成之后完成一个分支,该服务不再能够接收对其他操作的请求侦听的建模。
这可能是完全是您希望一些的方案中,但在其他希望工作流之前移动处理整个组的操作。
也就是您知道工作流将接收该服务合同中的多个请求在不同的操作,但您不确定哪个请求将第一个。
在这种情况下而不是在侦听活动可以使用包含一个其CanCreateInstance属性设为True的接收活动的每个分支中使用并行活动。
这仍允许与任何的操作启动工作流但它还在工作流状态以接收所有其他操作调用各种分支中的建模。
最后,使用状态机工作流时,可以更灵活地接收到一个特定的消息时,工作流的行为方式。
请考虑用初始状态包含多个事件驱动活动,每个接收活动作为起始活动,和每个接收标记为启用创建状态机。
正常情况下,将State活动的作用很像在侦听活动,但是作为开发人员,您决定从当前的状态移到另一个状态的控件时。
侦听活动完成关闭,,然后控件将移动到序列中下一个活动。
一个状态的活动与一个分支执行如果工作流没有移动到新的状态后工作流处于当前状态并继续等待已定义的输入。
若要用于语义Listen活动,如必须使用SetState活动调用的一个操作时,将工作流移动到下一状态。
这通常会使工作流进入在其中它正在等待要调用的不同WCF操作状态。
如果另一方面,要语义更接近但不是特定的顺序必须调用的所有操作的位置对并行模型,然后在每个接收活动后您可以选择不更改状态或恢复到相同的状态是self-transition使用转换SetState活动。
最后一个选项不是完全像并行活动模型一个潜在的重要方式。
与并行活动,已调用的操作后,它不能调用再次除非仿效并行活动的位置。
状态机器模型中,在工作流处于相同的状态,如果调用该操作后它可以接收消息的其他操作或原始操作。
在起的方式作用状态可以提供您语义类似于一个Listen活动在一个时活动,等待所有的事件,一个单独的事件响应和循环回然后等待这些相同的所有事件。
请将您想询问的问题和提出的意见发送至mmnet30@。
MattMilner是在Pluralsight,他连接的系统的技术(WCFWindows流,BizTalk,"Dublin,"的焦点位置在技术人员的成员和天蓝色服务平台)。
Matt也是一个独立的顾问特殊化Microsoft.NET应用程序设计和开发中。
Matt定期共享本地、地区,和国际会议,如技术来说他爱的技术。
Ed。
Microsoft已作为Matt的周围连接的系统的技术其团体的贡献的MVP。
联系人Matt通过他的博客
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Windows 工作流设计模式 工作流 设计 模式