工作流编程循序渐进(9:使用本地服务在宿主和工作流之间通信)
工作流编程循序渐进(9:使用本地服务在宿主和工作流之间通信)
[摘要]
一、简介
二、与本地服务相关的两个重要活动-HandleExternalEventActivity和 CallExternalMethodActivity
首先,让我们看一下MSDN中有关解释。
有关在工作流中使用 Web 服务的实例,将在后面文章中陆续给出。 |
来自MSDN: |
[1]HandleExternalEventActivity 活动与 CallExternalMethodActivity 活动结合使用,可输入或输出与本地服务的通信。 可以直接对一般通信使用这些活动。 或者,可以创建 HandleExternalEventActivity 和 CallExternalMethodActivity 类的子类,以创建严格绑定到某个接口上的特定事件和方法的活动,并具有 ExternalDataExchangeAttribute 属性。
HandleExternalEventActivity 基类阻止工作流,直到通过 WorkflowRuntime 注册的相应本地服务引发由 InterfaceType 和 EventName 属性指定的事件。 引发该事件后,或者如果该事件在活动开始执行前引发,则将传入数据分配给在 ParameterBindings 集合中定义的绑定位置。
[2]CallExternalMethodActivity 活动和 HandleExternalEventActivity 活动可用于与本地服务进行输入和输出通信。 您可以直接使用这些活动进行一般通信,也可以创建 CallExternalMethodActivity 和 HandleExternalEventActivity类的子类以创建一些活动,这些活动严格绑定到具有 ExternalDataExchangeAttribute属性的接口上的特定事件和方法。
CallExternalMethodActivity 基类调用由向 WorkflowRuntime 注册的相应本地服务的 InterfaceType 和 MethodName 属性指定的方法。 此调用是使用从绑定位置的 ParameterBindings 集合中收集的参数以同步方式执行的。 如果该方法具有返回值,则会在活动执行完毕前将这些值设置为绑定位置。
|
三、局部步骤归纳
接口定义举例(来自MSDN): |
[ExternalDataExchange] public interface ICommunicationService {
void HelloHost(string message);
event EventHandler<ExternalDataEventArgs> HelloWorkflow;
} |
自定义本地服务类举例(来自MSDN): |
public class CommunicationService : ICommunicationService {
public event EventHandler<ExternalDataEventArgs> HelloWorkflow;
public void HelloHost(string message)
Console.WriteLine("This is the message: {0}", message);
//引发HelloWorkflow事件
HelloWorkflow(null, new
ExternalDataEventArgs(WorkflowEnvironment.WorkflowInstanceId));
}
} |
在启动工作流之前需要完成的任务示例: |
ExternalDataExchangeService externalService = new ExternalDataExchangeService(); workflowRuntime.AddService(externalService); externalService.AddService(new CommunicationService()); |
注意:因为每个服务只能具有单个实例,因而有可能有多个工作流实例同时调用服务中的方法和事件。因此在设计时需要考虑线程安全的数据访问问题。 |
四、案例分析
(一)创建控制台顺序工作流示例框架
1. 启动VS2008,单击菜单”文件“|”新建“|”项目“,选择“Sequential Workflow Console Application”模板创建一个名字为LocalServiceDemo的控制台状态机工作流示例程序。
2.之后,系统自动打开工作流设计器界面。
3. 从工具箱中拖动几个活动到工作流设计器中,得到如图所示的情形。
(二)创建自定义事件参数类
创建自定义事件参数类(用于在宿主与工作流间传递参数之用): |
class CustomServiceEventArgs:ExternalDataEventArgs { private string name; //这个公共属性用于在宿主与工作流间传递参数之用,可以是复杂的类,也可以是简单的字符串 public string Name { get { return this.name; } } public CustomServiceEventArgs(Guid instanceID, string name) |
(三)定义本地服务接口
本地服务接口定义: |
[ExternalDataExchange] internal interface ICustService { event EventHandler<CustomServiceEventArgs> Approved; event EventHandler<CustomServiceEventArgs> Rejected; void CreateBallot(string name);//产生一次新的投票 } |
(四)定义本地服务类
IVotingService接口的类。该类将实现CreateBallot(),并触发这两个事件,代码如下所示。
定义本地服务类: |
internal class CustServiceImpl : ICustService { #region ICustService 成员 public event EventHandler<CustomServiceEventArgs> Approved; public event EventHandler<CustomServiceEventArgs> Rejected; public void CreateBallot(string name) public void ShowDlg(CustomServiceEventArgs args) result = MessageBox.Show(string.Format("是否同意,{0}", name), if (DialogResult.Yes == result) |
[注意]为了使用MessageBox和DialogResult,需要在项目上右击“引用”菜单,添加对System.Windows.Forms的引用。
(五)工作流编程
///定义了一个公共根属性,以便于接收从宿主传入的投票人信息。 //定义一个表示投票人姓名信息的属性 private string votername; public string VoterName { set { this.votername = value; } get { return this.votername; } } |
(六)控制台宿主编程
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Workflow.Runtime; using System.Workflow.Runtime.Hosting; using System.Workflow.Activities;//ExternalDataExehangeService //加载本地服务 //将自定义的本地通信服务加载到本地服务中 AutoResetEvent waitHandle = new AutoResetEvent(false); //向工作流实例传递参数,注意格式 WorkflowInstance instance = workflowRuntime.CreateWorkflow( waitHandle.WaitOne(); Console.Read(); |
(七)观察运行结果
单击“是”按钮后,得到如下结果:
五、部分参考资料
工作流编程循序渐进(9:使用本地服务在宿主和工作流之间通信)相关推荐
- 工作流编程循序渐进(3:While活动)
工作流编程循序渐进(3:While活动) 作者 朱先忠 一.引言 本文中,我们来学习另一个简单活动--While活动.While活动将会持续循环的执行,直至指定判断为假. 下面,我们来构建一个简单的 ...
- Qt:Windows编程—Qt实现本地服务管理
Qt实现本地服务管理 前言 本节将使用Windows的几个API,使用qt实现 本地服务 简单管理.这里简单介绍下服务. 几乎每一种操作系统都有一种在系统启动时启动的进程机制,这种机制不会依赖于用户的 ...
- WF(9):本地服务之事件处理
一:先来介绍两个活动 EventDrivenActivity和 ListenActivity. EventDrivenActivity是一个等侍事件触发的容器,EventDrivenActivity第 ...
- 坚持学习WF(8):本地服务之调用外部方法
WF提供了一组核心服务,例如在SQL 数据库中存储工作流实例的执行详细信息的持久性服务,计划服务,事务服务和跟踪服务.除了这些WF也提供了另外一种服务,叫做Local Service也可以叫做Data ...
- java linux 管理系统_用Java开发一个本地服务管理软件
使用Java开发一个本机服务管理程序,能够控制本机Tomcat.Apache服务的开启和关闭,图形界面控制.用户可以自己扩展其他服务,用来学习图形界面编程.多线程.事件响应等都不错. 一.最终界面 先 ...
- centos7 搭建本地git_本地服务调用K8S环境中的SpringCloud微服务实战
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:原创文章分类汇总及配套源码,涉及Java.Docker.K8S.Devops等 下图是典型的微 ...
- windows的服务中的登录身份本地系统账户、本地服务账户和网络服务账户修改
以一个redis服务为例: 一个redis注册服务后一般是网络服务账户,但是当系统不存在网络服务账户时,就会导致redis服务无法正常启动.接下来修改redis服务的登录身份. cmd下输入如下命令: ...
- Android Service学习之本地服务
Service是在一段不定的时间运行在后台,不和用户交互应用组件.每个Service必须在manifest中 通过<service>来声明.可以通过contect.startservice ...
- 增加 oracle服务名,oracle本地服务名配置说明
本地oracle客户端连接远程oracle数据库服务器配置说明如下: 1.找到本地oracle客户端安装目录,如:%path%\Oracle 2.再找配置文件tnsnames.ora,其目录为 %pa ...
最新文章
- ORACLE设置用户密码不过期
- wave格式分析,wave音频文件格式分析配程序
- quartz源码解析--转
- 深入分析 iBATIS 框架之系统架构与映射原理--转载
- python基础(part8)--容器类型之元组和字典
- LeetCode 849. 到最近的人的最大距离
- 谷歌离开游览器不触发_谷歌游览器
- 【Flink】Flink Not all required tasks are currently running
- 华为全球分析师大会:HMS Core全球开发者应用集成的数量加速增长,打造全场景智慧体验...
- [HNOI2015]开店(树剖+主席树+标记永久化)
- [云计算]VXLAN的网关划分
- C语言科学计数法介绍和示例
- Java工程师的职业规划,上个月成功拿到阿里P7offer
- html怎么改变网页整体的大小,html设置浏览器大小
- 研华IO板卡驱动安装与PICE-1753(PCIE-1751)接线说明
- 数据库-进阶6-连接查询
- 拯救BUG 10五笔输入法Shift键切换中英文问题
- 错过这次,再等一年!视频云CDN全线折扣Hi购启动...
- 新浪博客和微博已经成为黄色网站的…
- 简单的数据结构介绍(栈、队列、数组、链表、红黑树)
热门文章
- Java项目:在线商城系统(前后端分离+java+vue+Springboot+ssm+mysql+maven+redis)
- python创建mysql数据库_python 怎么创建create mysql的数据库
- 基于SSM实现二手交易系统
- CocoaPods私有库搭建的记录
- H5使用百度地图SDK获取用户当前位置并且标记显示在地图
- js 微信小程序日期 时间转时间戳
- 【微信小程序之画布】四:手指触摸绘波浪线
- ScratchCardView:刮刮卡视图组件
- Linux Mint 19 安装Gnome Boxes 新建失败
- pfSense book之2.4安装指南