Welcome

首页 / 软件开发 / .NET编程技术 / WF从入门到精通(第十章):事件活动

WF从入门到精通(第十章):事件活动2010-06-03 cnblogs GuoYong.Che学习完本章,你将掌握:

1.使用HandleExtenalEvent活动创建特定的事件处理程序

2.在你的工作流中使用Delay活动

3.在你的工作流中使用EventDriven活动

4.在你的工作流中使用Listen活动

5.理解EventHandlingScope活动在活动并发执行的情况下是怎样监听事件的

在第八章(“调用外部方法和工作流”)中,你看过工作流怎样使用CallExternalMethod活动来和宿主应用程序进行通信。当工作流调用一个外部方法时,使用一个你提供的本地通信服务,该宿主应用程序会收到一个事件,然后宿主对数据进行处理并产生一些相应的动作。

相反的调用过程是宿主应用程序触发的事件被工作流捕获进行处理(尽管工作流事件处理可被用在更广泛的任务中,而不仅仅是和宿主进行通信)。在第八章中,我提到过在对工作流用来处理事件的活动进行叙述后,我们还将重温宿主/工作流之间的通信,在本章中我们将完成这件事。

在目前为止的其它章节中,我都是单独地对某个工作流活动进行描述,然后提供一个小应用程序来演示该活动的操作过程。和这些章节不同,本章将在一个示例应用程序中对多个活动进行描述和演示。为什么这样做呢?因为我在这里要描述的这些活动都是相互关联互相依赖的。我不能演示其中一个活动而对其它的活动不进行演示。Listen活动可作为EventDriven活动的容器。在EventDriven活动的内部,你还会不出所料找到唯一的一个HandleExternalEvent活动等等。因此在本章中我将从始至终只创建一个应用程序来对这些活动进行描述和演示。“宿主到工作流”这一节是本章的主线。我们首先从HandleExternalEvent活动开始。

使用HandleExternalEvent活动

不管在你的工作流中在何处处理事件,也不管你的工作流正处于执行状态时所发现要执行的是什么样的活动组合,只要当一个事件来到了你的工作流路径当中,HandleExternalEvent活动就是最终去处理该事件的工作流活动。对我来说,.NET的强大的功能特性很多,它的触发和处理事件的能力就是这些最强大的功能中的一个。包括工作流事件的处理也同样强大。

HandleExternalEvent活动的作用是响应一个基于IEventActivity接口的事件,它有三个主要的成员:QueueName属性、Subscribe和Unsubscribe方法。QueueName表示正等待该事件的工作流队列,而Subscribe和Unsubscribe方法用来把你的事件处理程序将要接收(或者不将进行接收)的特定事件实例告知工作流运行时。

HandleExternalEvent活动本身也可和CallExternalMethod活动一起使用(我们在第8章中看到过)。工作流使用CallExternalMethod活动来把数据发送给宿主应用程序,但是在工作流执行时,工作流使用HandleExternalEvent来接收从宿主中发送过来的数据。

备注:牢记:使用外部数据交换的时机并不仅仅是在把数据从你的宿主应用程序发送到工作流的时候。当你创建你的工作流实例的时候,你可总是为其提供初始数据。但是,一旦工作流正在执行时,对于直接和你的宿主应用程序进行本地通信来说,它是唯一可使用的机制(当然也可使用更加间接的方式替代,例如使用FTP协议或者Web服务调用这些手段)。

表10-1和表10-2列出了使用HandleExternalEvent活动时经常用到的一些主要的属性和方法。注意有些方法和属性是所有活动共有的(如在第四章“活动和工作流类型介绍”中表4-1和表4-2展示的一样)。我在此展示的属性和方法无疑不是所有可使用的属性和方法,但他们却是经常要被用到的。

表10-1经常用到的HandleExternalEvent活动的属性

属性功能
CorrelationToken获取或设置一个到关联标记(correlation token)的绑定。我们将在第17章(“关联和本地宿主通信”)中处理关联。
EventName活动将要处理的事件。注意如果没有对其进行设置,该活动将不会对事件进行监听并且和宿主通信也就不可能进行。奇怪的是,忽略该属性值你不会收到任何错误验证信息。
InterfaceType获取或设置进行通信所要使用的接口类型。该接口必须使用ExternalDataExchange特性进行装饰(标记)。(你或许可回忆一下第8章,你为CallExternalMethod方法提供了一个相同的接口。)

表10-2经常用到的HandleExternalEvent活动的方法

方法功能
OnInvoked这是一个有很用的保护型(protected)方法,它用来把本事件参数中的值和你工作流中的字段或依赖属性进行绑定。重写该方法(或者处理它所触发的事件)是检索来自于宿主并被保存到事件参数中的数据一个主要的机制,通常,你会创建一个自定义的事件参数来把数据嵌入进参数对象自身中。

尽管你能直接从Visual Studio的工具箱中使用HandleExternalEvent活动,但更普遍的情形是使用你在第8章中看过的wca.exe工具来为你正使用的通信接口创建一个派生自HandleExternalEvent的自定义类。例如,假如在你的接口中定义了一个名称为SendDataToHost的事件,wca.exe将会生成一个称作SendDataToHost的新活动(它派生自HandleExternalEvent),并为你指定了EventName和InterfaceType,而且通过你创建的事件参数也为你和SendDataToHost事件进行了数据绑定。在本章晚些时候我将提供一个例子。

 

使用HandleExternalEvent很容易,只需简单地在你的工作流中放入该活动,指定接口和事件名。假如你需要的话,还可为Invoked事件提供一个event handler,然后就可执行你的工作流了。假如你使用wca.exe,就可为你提供一个派生自HandleExternalEvent的活动,你可直接把它拖拽到你的工作流中,在属性窗口中添加绑定,把事件参数中的数据和一个局部字段或者依赖属性绑定在一起。

在你的工作流中有了HandleExternalEvent活动后,在等待事件发生时所有通过该顺序流的处理过程都会停止。在一定程度上,在你的工作流中放入这个活动的行为就像.NET Framework编程术语中的AutoResetEvent。和AutoResetEvent不同的是,该处理过程的线程不是暂停。它就像是一扇门或通道,只有在该事件被触发时才允许工作流处理过程沿着它的路径次序继续前进。