一:当我们在工作流中使用本地服务的事件的时候,WF运行时引擎将入站消息映射到实例中的特定的HandleExternalEventActivity活动,对实例的映射是在将工作流实例InstanceId传递到ExternalDataEventArgs构造函数时完成的。所以当工作流实例在本地服务接口上侦听相同事件的不同实例时,就无法确定该响应哪个事件。如下图:
如何解决这个问题呢,我们就需要在工作流中使用关联,通过使用接口属性来定义关联,使用关联后通信活动会多出一个CorrelationToken属性(关联标记)。当宿主中要触发一个外部事件时,可以传递两个参数,一个是实例的ID号,一个是关联标记编号。这样就可以将事件路由到该工作流实例中正确的活动。
使用关联时要成对使用CallExternalMethodActivity与HandleExternalEventActivity。
下面看下关联的接口属性:
CorrelationParameterAttribute
用于指定在接口中定义的方法和事件的用于关联的参数名称。 如果方法或事件包含一个与该名称匹配的形参,则该参数定义该方法或事件上的相关值。 如果方法或事件没有此类参数,则方法或事件可以使用 CorrelationAliasAttribute 来定义相关值的位置。 此属性在一个接口中可以出现多次。
CorrelationInitializerAttribute
用于在方法或事件中指示相关参数的值是在调用该方法或引发该事件时初始化的。 对于给定的 CorrelationToken,必须在对话中的任何其他方法或事件执行之前调用或接收初始值设定项方法或事件。 任何可以初始化新对话(即新的相关令牌)的方法或事件都必须使用此属性进行标记。 对于每个相关令牌,方法或事件必须包含一个适当的命名参数或一个 CorrelationAliasAttribute。
CorrelationAliasAttribute
在方法或事件定义中用来重写该成员的 CorrelationParameter 设置。 CorrelationAliasAttribute 属性指定可用参数中可以获得相关值的位置。 该字符串参数是针对形参集的以点分隔的路径。 该参数指示在何处可以找到匹配数据值。 如果定义了多个相关令牌,还必须指定令牌 Name 命名参数。
二:下面是个小例子,该示例中工作流将创建两个任务,然后在这些任务完成时等待(同一本地服务事件)通知。 在这种情况下,当外部代码将事件引发到工作流时,本地服务基础结构必须依赖于所引发事件中的数据(相关值)将事件路由到工作流实例中相应的 HandleExternalEventActivity 活动。
每创建一项任务,任务服务就会显示一个消息框,通知用户任务已创建。 单击了“确定”按钮后,将为对应的任务 ID 引发用以完成任务的事件。 这些属性与 CreateTask 活动上设置的属性相同,因此事件与正确的 TaskCompleted 活动关联。
1.事件参数类TaskEventArgs:
public class TaskEventArgs : ExternalDataEventArgs
{
string idValue;
string assigneeValue;
string textValue;
public TaskEventArgs(Guid instanceId, string id, string assignee, string text)
:base(instanceId)
{
this.idValue = id;
this.assigneeValue = assignee;
this.textValue = text;
}
public string Id
{
get { return this.idValue; }
set { this.idValue = value; }
}
public string Assignee
{
get { return this.assigneeValue; }
set { this.assigneeValue = value; }
}
public string Text
{
get { return this.textValue; }
set { this.textValue = value; }
}
}
2.定义服务接口:
[CorrelationParameter("taskId")]
public interface ITaskService
{
[CorrelationInitializer]
void CreateTask(string taskId, string assignee, string text);
[CorrelationAlias("taskId", "e.Id")]
event EventHandler<TaskEventArgs> TaskCompleted;
}
注意:2.1 [CorrelationParameter("taskId")] 中的"taskId"和CreateTask方法中的string taskId要一致。
2.2 [CorrelationAlias("taskId", "e.Id")] 关联参数的别名绑定。
3.实现服务类:
{
public void CreateTask(string taskId, string assignee, string text)
{
Console.WriteLine("task " + taskId + " created for " + assignee);
ThreadPool.QueueUserWorkItem(ShowDialog, new TaskEventArgs(WorkflowEnvironment.WorkflowInstanceId, taskId, assignee, text));
}
public void RaiseEvent(TaskEventArgs args)
{
EventHandler<TaskEventArgs> taskCompleted = this.TaskCompleted;
if (taskCompleted != null)
taskCompleted(null, args);
}
public void ShowDialog(object state)
{
TaskEventArgs taskEventArgs = state as TaskEventArgs;
MessageBox.Show(string.Format("{0}, click OK when '{1}' completed.", taskEventArgs.Assignee, taskEventArgs.Text), string.Format("Task {0}", taskEventArgs.Id), MessageBoxButtons.OK);
RaiseEvent(taskEventArgs);
}
public event EventHandler<TaskEventArgs> TaskCompleted;
}
4.创建自定义通信活动
4.1 CreateTask活动继承自CallExternalMethodActivity,来调用本地服务中的方法,在构造函数中设定InterfaceType和MethodName属性。代码如下:
[ToolboxItemAttribute(typeof(ActivityToolboxItem))]
public partial class CreateTask : System.Workflow.Activities.CallExternalMethodActivity
{
// Properties on the task
public static DependencyProperty AssigneeProperty = DependencyProperty.Register("Assignee", typeof(System.String), typeof(Microsoft.Samples.Workflow.CorrelatedLocalService.CreateTask));
public static DependencyProperty TaskIdProperty = DependencyProperty.Register("TaskId", typeof(System.String), typeof(Microsoft.Samples.Workflow.CorrelatedLocalService.CreateTask));
public static DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(System.String), typeof(Microsoft.Samples.Workflow.CorrelatedLocalService.CreateTask));
private void InitializeComponent()
{
}
public CreateTask()
{
this.InterfaceType = typeof(Microsoft.Samples.Workflow.CorrelatedLocalService.ITaskService);
this.MethodName = "CreateTask";
}
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
[BrowsableAttribute(true)]
public string Assignee
{
get
{
return ((string)(base.GetValue(Microsoft.Samples.Workflow.CorrelatedLocalService.CreateTask.AssigneeProperty)));
}
set
{
base.SetValue(Microsoft.Samples.Workflow.CorrelatedLocalService.CreateTask.AssigneeProperty, value);
}
}
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
[BrowsableAttribute(true)]
public string TaskId
{
get
{
return ((string)(base.GetValue(Microsoft.Samples.Workflow.CorrelatedLocalService.CreateTask.TaskIdProperty)));
}
set
{
base.SetValue(Microsoft.Samples.Workflow.CorrelatedLocalService.CreateTask.TaskIdProperty, value);
}
}
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
[BrowsableAttribute(true)]
public string Text
{
get
{
return ((string)(base.GetValue(Microsoft.Samples.Workflow.CorrelatedLocalService.CreateTask.TextProperty)));
}
set
{
base.SetValue(Microsoft.Samples.Workflow.CorrelatedLocalService.CreateTask.TextProperty, value);
}
}
protected override void OnMethodInvoking(EventArgs e)
{
this.ParameterBindings["taskId"].Value = this.TaskId;
this.ParameterBindings["assignee"].Value = this.Assignee;
this.ParameterBindings["text"].Value = this.Text;
}
}
4.2 TaskCompleted活动继承自HandleExternalEventActivity,来处理本地服务中的事件,在构造函数中设定
InterfaceType和EventName属性。代码如下:[ToolboxItemAttribute(typeof(ActivityToolboxItem))]
public partial class TaskCompleted : System.Workflow.Activities.HandleExternalEventActivity
{
// properties
public static DependencyProperty SenderProperty = System.Workflow.ComponentModel.DependencyProperty.Register("Sender", typeof(Object), typeof(TaskCompleted));
public static DependencyProperty EProperty = System.Workflow.ComponentModel.DependencyProperty.Register("E", typeof(TaskEventArgs), typeof(TaskCompleted));
align=发表评论
-
平淡的2007
2007-12-24 08:04 782早上起来,送女朋友去公交车站,然后回来赶紧打开电脑,先 ... -
DreamSpark发布,高校学生免费使用Visual Studio 2008 Professional Edition 等微软软件
2008-02-20 13:23 1378今天上网无意中搜索到学生可以免费使用VS2008专业版,后来又 ... -
坚持学习WF(1):从HelloWorld开始
2008-04-04 16:30 847[置顶]坚持学习WF文章索 ... -
坚持学习WF(2):WF创作模式和设计时工具
2008-04-05 17:19 597[置顶]坚持学习WF文章索 ... -
坚持学习WF(3):WF框架概览
2008-04-08 07:27 734[置顶]坚持学习WF文章索 ... -
坚持学习WF(4):活动(Activity)和依赖属性(DependencyProperty)
2008-04-12 00:01 1100[置顶]坚持学习WF文章索引 活动(Activity) 活动 ... -
坚持学习WF(5):自定义活动(CustomActivity)
2008-04-13 15:25 881当WF提供的标准活动不能满足我们的需求的时候,我们就需要定义自 ... -
MOSS点滴(1):如何开发和部署feature
2008-04-16 21:35 805Features 是MOSS 2007以开箱即用的一套新功能, ... -
MOSS点滴(2):自定义Application Page
2008-04-19 20:07 808在MOSS中后台管理的页面都是Application Pag ... -
坚持学习WF(6):开发可复用的宿主程序
2008-04-21 21:45 659我们之前写工作流宿主 ... -
MOSS点滴(3):说说MOSS中的母版页
2008-04-25 21:15 1134MOSS中有两种页面:Site P ... -
MOSS点滴(4):实现Form认证
2008-04-29 21:12 665本文主要参考了网上的一些文章,但有些文章有些地方说的不是很明确 ... -
坚持学习WF(7):流程控制(Flow Control)
2008-04-30 18:10 771本文主要说说WF中和流 ... -
坚持学习WF(8):本地服务之调用外部方法
2008-05-09 08:17 717WF提供了一组核心服务 ... -
MOSS中的WebPart开发
2008-05-10 13:53 1023由于在asp.net1.1的时候asp.net中还没有webp ... -
坚持学习WF(9):本地服务之事件处理
2008-05-28 07:49 763[置顶]坚持学习WF文章索引 一:先来介绍两个活动 Even ... -
坚持学习WF(11):工作流通信与队列
2008-06-07 15:45 691[置顶]坚持学习WF文章索引 WF 提供的通信模型是构建于 ... -
MOSS中创建自定义内容类型
2008-06-12 20:23 1068一:简要介绍 某类内容 ... -
.NET中IDisposable接口的基本使用
2008-06-15 12:01 907首先来看MSDN中关于这个接口的说明: [ComVisible ... -
坚持学习WF(12):使用EventHandlingScopeActivity活动
2008-06-18 22:46 639[置顶]坚持学习WF文章索引 EventHandlingSco ...
相关推荐
坚持学习WF(10):在工作流中使用关联 当工作流实例在本地服务接口上侦听相同事件的不同实例时,就无法确定该响应哪个事件。如何解决这个问题呢,我们就需要在工作流中使用关联。 坚持学习WF(11):工作流通信与队列 ...
坚持学习WF(10):在工作流中使用关联 当工作流实例在本地服务接口上侦听相同事件的不同实例时,就无法确定该响应哪个事件。如何解决这个问题呢,我们就需要在工作流中使用关联。 坚持学习WF(11):工作流通信与队列 WF...
坚持学习WF(1):从HelloWorld开始 本文主要通过实现了一个可以接受参数的HelloWorld程序来了解WF。 坚持学习WF(2):WF创作模式和设计时工具 坚持学习WF(3):WF框架概览 2.3两篇主要全面的阐述了WF框架和Visual ...
WF工作流例子
这个例子以一个报销流程为例,从员工(staff)发起报销流程开始,提交给经理...是学习微软WF工作流的一个好例子! 数据库在文件夹里,直接还原即可,不用附加。 ps:有同样喜欢研究工作流的朋友可以+10007354共同进步!
WF的全称是Windows Workflow Foundation,是微软在.NET 3.0之后推出的一套工作流开发框架。WF是微软在.NET 3.0上推出的三大框架(WPF和WCF及WF)之一,其主要目的在于为现有的.NET应用程序嵌入工作流应用,目前最新...
坚持学习WF(1):从HelloWorld开始 源码
工作流系统是以规格化的流程描述作为...该节主要包括以下内容:实现技术与实现方案、工作流设计器、工作流调用服务(封装类、WFLocalService和WFWebService)、工作流分类、工作调用、工作流监控、页面流和工作流权限等
坚持学习WF(5):自定义活动(CustomActivity) 源码
WWF技术的学习资料
这是关于工作流的学习pdf格式的文档:WF从入门到精通
WF工作流的一个完整例子,是基于之前发存的WF调试器的加架写的
这是一个压强包里面有几十个项目,供学习参考。
WPF+WF+Linq 工作流的例子WPF+WF+Linq 工作流的例子WPF+WF+Linq 工作流的例子
1. WF基础知识 ...4.IMS工作流使用帮助 第一步 设置工作流运行时环境变量 第二步 使用全局属性 第三步 绘制流程图 第四步 发布流程 第五步 编写代码 第六步 配置参数 第七步 调试运行 注意事项
基于WF工作流引擎的 高效OA 源码,基于微软NET架构的云在线办公系统,支持多公司架构,SaaS软件按模式。非常适合公司或团队使用,可以作为通用OA的基础模式,代码完整,功能几乎无错,正在使用运行。
微软工作流的学习的文档微软工作流的学习的文档微软工作流的学习的文档微软工作流的学习的文档微软工作流的学习的文档微软工作流的学习的文档微软工作流的学习的文档微软工作流的学习的文档微软工作流的学习的文档...
非常值得学工作流的参考的 并且使用的思想也很好
WF 会议签到例子 WF 博客申请流程 WF 设计器
一个.net WF的纯Web工作流设计器,能生成xoml内容