(转载)Windows workflow foundation(二)——(创建状态机工作流)(上)

简介:

状态机工作流是为事件驱动的工作场景设计的。一个状态机工作流包含两个或两个以上的状态,且任意时刻只有一个处于激活状态。在这一节中,我们将创建一个基于状态机的工作流,这个工作流将通过其内部不同的状态,来处理宿主程序提交的订单。初始状态为WaitForOrderState只要宿主程序提交了一个新订单,这个状态就会执行。当收到一个新订单后,进入OrderProcessing状态开始处理订单。最后一个状态就是OrderCompletedState。在这个过程中,不同的状态将会与宿主程序交互。

创建一个状态机工作流

一个状态机工作流可以继承从StateMachineWorkflow类,这个类中已经实现了状态机工作流的大部分功能。一旦你继承了这个类,你就可以开始在工作流中加入所需的状态,并使用SetState活动或事件驱动的活动如EventSink把这些状态连接起来。以下的代码就是我们的工作流类OrderProcessingWorkflow,这个类是接下来整个示例程序的基础。你可能已经注意到了,类中声明了两个变量。这两个变量是用来存贮当前订单信息的,这些信息将会在整个流程中用到。

using System;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;

namespace Microsoft.Samples.Workflow.Quickstarts.StateMachine
{
public partial class OrderProcessingWorkflow : StateMachineWorkflow
{
private string orderId;
private string itemStatus;

public OrderProcessingWorkflow()
{
InitializeComponent();
}

private void InitializeComponent()
{
}

}

}

创建活动和参数绑定

WWF中有两个类ActivityBindParameterBinding,是专门用来将活动中的变量,绑定到方法调用所需的参数上的。这个方法定义在一个接口中,接口的实现就是注册到工作流中的服务。在我们的程序中,我们将把当前订单的orderIdstatus的值传递进去。以下的代码示例了如何创建和联系工作流的私有变量和参数。这些参数将用来根据当前工作流的状态来更新宿主。在稍后创建状态活动时,我们将用到这些绑定对象。

开始创建活动和参数绑定

1. 定义一个私有变量

类型

名称

ActivityBind

orderIdActivityBind

ParameterBinding

orderIdParameterBinding

ActivityBind

itemStatusActivityBind

ParameterBinding

itemStatusParameterBinding

2. 以下代码示例了如何创建ActivityBindParameterBinding,以及怎样和私有变量绑定。

//
// Binding variables
//
orderIdActivityBind = new ActivityBind();
orderIdParameterBinding = new ParameterBinding();
itemStatusActivityBind = new ActivityBind();
itemStatusParameterBinding = new ParameterBinding();

orderIdActivityBind.ID = "/Workflow";
orderIdActivityBind.Path = "orderId";
orderIdParameterBinding.ParameterName = "orderId";
orderIdParameterBinding.SetBinding(System.Workflow.ComponentModel.ParameterBinding.ValueProperty,
((System.Workflow.ComponentModel.Bind)(orderIdActivityBind)));

itemStatusActivityBind.ID = "/Workflow";
itemStatusActivityBind.Path = "itemStatus";
itemStatusParameterBinding.ParameterName = "newStatus";
itemStatusParameterBinding.SetBinding(System.Workflow.ComponentModel.ParameterBinding.ValueProperty,
((System.Workflow.ComponentModel.Bind)(itemStatusActivityBind)));

构造WaitingForOrder状态

这第一个状态监听来自宿主的事件,这个事件通知工作流一个新的订单已经被提交了,应该马上处理它。当你创建状态时,状态的第一个子活动必须是StateInitialization活动或实现了IEventActivity接口的活动。这里的WaitForOrderState采用了后者,因为这个状态是由宿主程序的事件激活的。

EventSink活动是用来监听注册在WWF运行库中的服务的事件的,在我们的程序中,这个服务由宿主程序提供。我们在工作流中定义了IOrderingService接口,这个接口稍后将由宿主程序实现。

using System;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime.Messaging;

namespace Microsoft.Samples.Workflow.Quickstarts.StateMachine
{
[Serializable]
public class NewOrderEventArgs : WorkflowMessageEventArgs
{
private string item;
private int quantity;

public NewOrderEventArgs(Guid instanceId, string item, int quantity)
: base(instanceId)
{
this.item = item;
this.quantity = quantity;
}

public string Item
{
get { return item; }
set { item = value; }
}

public int Quantity
{
get { return quantity; }
set { quantity = value; }
}
}

[DataExchangeService]
public interface IOrderingService
{
void ItemStatusUpdate( string orderId, string newStatus);
event EventHandler<NewOrderEventArgs> NewOrder;
}
}

一旦EventSink活动处理了触发事件后,一个状态消息需要通过IOrderingInterface发回宿主程序。工作流需要调用接口中的ItemStatusUpdate方法,并传递orderIdnewStatues参数。而调用接口方法的工作,就交给InvokeMethodActivity活动了。我们指定活动的InterfaceType参数为我们需要的服务接口,MethodName属性设为要调用的服务接口中的方法名称,然后在ParameterBindings中加入之前构造好的参数绑定,最后为活动的MethodInvoking事件指定一个事件处理程序,用来改变当前订单的状态。因为我们已经把orderIdnewStatus参数绑定到了私有变量orderIditemStatus上,所以为ItemStatusUpdate方法传递参数的过程是由WWF运行库自动完成的。

更新完成之后,WaitingForOrderState状态已经准备好转移下一个状态——OrderOpenState(译者注:这里错了,应该是OrderPrecessingState)状态。SetState活动是专门负责状态转移的。把一个SetState活动加入到EventDriven的最后一环,当一切处理完后,SetState活动将执行,并立马跳转到指定的下一个状态。

开始构造WaitForOrderState

1. 定义5个私有变量

类型

名称

EventSinkActivity

newOrderEventSink

InvokeMethodActivity

updatestatusOrderReceived

SetState

setStateOrderProcessing

EventDriven

eventDriven1

State

WaitingForOrderState

2. 用默认构造函数实例化以上变量

以下代码演示了如何构造WaitForOrderState。先是EventSinkActivity来处理宿主事件,然后InvokeMethodActivity来改变当前订单状态,并更新宿主状态。最后,SetState活动将WaitForOrder状态转移到OrderPrecessing状态。把这三个活动就依次加入到EventDriven活动的子活动中。

//
// WaitingForOrder State
//
this.newOrderEventSink = new System.Workflow.Activities.EventSinkActivity();
this.newOrderEventSink.EventName = "NewOrder";
this.newOrderEventSink.ID = "newOrderEventSink";
this.newOrderEventSink.InterfaceType = typeof(Microsoft.Samples.Workflow.Quickstarts.StateMachine.IOrderingService);
this.newOrderEventSink.Roles = null;

this.updatestatusOrderReceived = new System.Workflow.Activities.InvokeMethodActivity();
this.updatestatusOrderReceived.ID = "updatestatusOrderReceived";
this.updatestatusOrderReceived.InterfaceType = typeof(Microsoft.Samples.Workflow.Quickstarts.StateMachine.IOrderingService);
this.updatestatusOrderReceived.MethodName = "ItemStatusUpdate";
this.updatestatusOrderReceived.ParameterBindings.Add(orderIdParameterBinding);
this.updatestatusOrderReceived.ParameterBindings.Add(itemStatusParameterBinding);
this.updatestatusOrderReceived.MethodInvoking += new System.EventHandler( this.OrderReceived);

this.setStateOrderProcessing = new System.Workflow.Activities.SetState();
this.setStateOrderProcessing.ID = "setStateOrderProcessing";
this.setStateOrderProcessing.TargetState = "OrderProcessingState";

this.eventDriven1 = new System.Workflow.Activities.EventDriven();
this.eventDriven1.Activities.Add( this.newOrderEventSink);
this.eventDriven1.Activities.Add( this.updatestatusOrderReceived);
this.eventDriven1.Activities.Add( this.setStateOrderProcessing);
this.eventDriven1.ID = "eventDriven1";

this.WaitingForOrderState = new System.Workflow.Activities.State();
this.WaitingForOrderState.Activities.Add( this.eventDriven1);
this.WaitingForOrderState.ID = "WaitingForOrderState";

你可以在InvokeMethodActivity活动执行的前一刻,加入一些附加的逻辑。只要为MethodInvoking事件指定一个处理程序,就能做到这一点。以下的代码就是MethodInvoking事件的处理程序。它为itemStatusorderId变量指定了新的值。事件处理程序的指定,已经在上面的代码中做了。

private void OrderReceived( object sender, EventArgs e)
{
itemStatus = "Received order";
orderId = Guid.NewGuid().ToString();
}



本文转自高海东博客园博客,原文链接http://www.cnblogs.com/ghd258/archive/2005/12/31/309163.html,如需转载请自行联系原作者
相关文章
|
消息中间件 Kafka Windows
Kafka Windows运行错误:创建消费者报错 consumer zookeeper is not a recognized option
Kafka Windows运行错误:创建消费者报错 consumer zookeeper is not a recognized option
689 0
Kafka Windows运行错误:创建消费者报错 consumer zookeeper is not a recognized option
|
vr&ar C# 图形学
WPF与AR/VR的激情碰撞:解锁Windows Presentation Foundation应用新维度,探索增强现实与虚拟现实技术在现代UI设计中的无限可能与实战应用详解
【8月更文挑战第31天】增强现实(AR)与虚拟现实(VR)技术正迅速改变生活和工作方式,在游戏、教育及工业等领域展现出广泛应用前景。本文探讨如何在Windows Presentation Foundation(WPF)环境中实现AR/VR功能,通过具体示例代码展示整合过程。尽管WPF本身不直接支持AR/VR,但借助第三方库如Unity、Vuforia或OpenVR,可实现沉浸式体验。例如,通过Unity和Vuforia在WPF中创建AR应用,或利用OpenVR在WPF中集成VR功能,从而提升用户体验并拓展应用功能边界。
298 1
|
开发者 C# Windows
WPF与游戏开发:当桌面应用遇见游戏梦想——利用Windows Presentation Foundation打造属于你的2D游戏世界,从环境搭建到代码实践全面解析新兴开发路径
【8月更文挑战第31天】随着游戏开发技术的进步,WPF作为.NET Framework的一部分,凭借其图形渲染能力和灵活的UI设计,成为桌面游戏开发的新选择。本文通过技术综述和示例代码,介绍如何利用WPF进行游戏开发。首先确保安装最新版Visual Studio并创建WPF项目。接着,通过XAML设计游戏界面,并在C#中实现游戏逻辑,如玩家控制和障碍物碰撞检测。示例展示了创建基本2D游戏的过程,包括角色移动和碰撞处理。通过本文,WPF开发者可更好地理解并应用游戏开发技术,创造吸引人的桌面游戏。
670 0
|
C# Windows 开发者
当WPF遇见OpenGL:一场关于如何在Windows Presentation Foundation中融入高性能跨平台图形处理技术的精彩碰撞——详解集成步骤与实战代码示例
【8月更文挑战第31天】本文详细介绍了如何在Windows Presentation Foundation (WPF) 中集成OpenGL,以实现高性能的跨平台图形处理。通过具体示例代码,展示了使用SharpGL库在WPF应用中创建并渲染OpenGL图形的过程,包括开发环境搭建、OpenGL渲染窗口创建及控件集成等关键步骤,帮助开发者更好地理解和应用OpenGL技术。
1022 0
|
存储 开发者 C#
WPF与邮件发送:教你如何在Windows Presentation Foundation应用中无缝集成电子邮件功能——从界面设计到代码实现,全面解析邮件发送的每一个细节密武器!
【8月更文挑战第31天】本文探讨了如何在Windows Presentation Foundation(WPF)应用中集成电子邮件发送功能,详细介绍了从创建WPF项目到设计用户界面的全过程,并通过具体示例代码展示了如何使用`System.Net.Mail`命名空间中的`SmtpClient`和`MailMessage`类来实现邮件发送逻辑。文章还强调了安全性和错误处理的重要性,提供了实用的异常捕获代码片段,旨在帮助WPF开发者更好地掌握邮件发送技术,提升应用程序的功能性与用户体验。
251 0
|
存储 安全 搜索推荐
微软发布 Windows 365:将 PC 置于云端,几分钟就能创建
微软发布 Windows 365:将 PC 置于云端,几分钟就能创建
261 0
微软发布 Windows 365:将 PC 置于云端,几分钟就能创建
|
PHP Windows
php windows多进程,php windows创建多进程,
php windows多进程,php windows创建多进程,
742 0
|
Shell 开发工具 git
如何在Windows上使用Git创建一个可执行脚本?
长话短说,今天介绍如何在windows上使用Git上创建一个可执行的shell脚本。
如何在Windows上使用Git创建一个可执行脚本?
|
开发工具 Python Windows
【开发环境】Windows 安装 PyCharm 开发环境 ( 下载 PyCharm | 安装 PyCharm | 在 PyCharm 中创建 Python 工程 )(三)
【开发环境】Windows 安装 PyCharm 开发环境 ( 下载 PyCharm | 安装 PyCharm | 在 PyCharm 中创建 Python 工程 )(三)
208 0
【开发环境】Windows 安装 PyCharm 开发环境 ( 下载 PyCharm | 安装 PyCharm | 在 PyCharm 中创建 Python 工程 )(三)
|
Python Windows
【开发环境】Windows 安装 PyCharm 开发环境 ( 下载 PyCharm | 安装 PyCharm | 在 PyCharm 中创建 Python 工程 )(二)
【开发环境】Windows 安装 PyCharm 开发环境 ( 下载 PyCharm | 安装 PyCharm | 在 PyCharm 中创建 Python 工程 )(二)
199 0
【开发环境】Windows 安装 PyCharm 开发环境 ( 下载 PyCharm | 安装 PyCharm | 在 PyCharm 中创建 Python 工程 )(二)