当工作流实例在本地服务接口上侦听相同事件的不同实例时,就无法确定该响应哪个事件
如何解决这个问题呢,我们就需要在工作流中使用关联,通过使用接口属性来定义关联,使用关联后通信活动会多出一个CorrelationToken属性(关联标记)。
当宿主中要触发一个外部事件时,可以传递两个参数,一个是实例的ID号,一个是关联标记编号。这样就可以将事件路由到该工作流实例中正确的活动。
使用关联时要成对使用CallExternalMethodActivity与HandleExternalEventActivity。
下面看下关联的接口属性:
CorrelationParameterAttribute
用于指定在接口中定义的方法和事件的用于关联的参数名称。 如果方法或事件包含一个与该名称匹配的形参,则该参数定义该方法或事件上的相关值。
如果方法或事件没有此类参数,则方法或事件可以使用 CorrelationAliasAttribute 来定义相关值的位置。 此属性在一个接口中可以出现多次。
CorrelationInitializerAttribute
用于在方法或事件中指示相关参数的值是在调用该方法或引发该事件时初始化的。 对于给定的 CorrelationToken,必须在对话中的任何其他方法或事件执行之前
调用或接收初始值设定项方法或事件。 任何可以初始化新对话(即新的相关令牌)的方法或事件都必须使用此属性进行标记。 对于每个相关令牌,方法或事件必须
包含一个适当的命名参数或一个 CorrelationAliasAttribute。
CorrelationAliasAttribute
在方法或事件定义中用来重写该成员的 CorrelationParameter 设置。 CorrelationAliasAttribute 属性指定可用参数中可以获得相关值的位置。
该字符串参数是针对形参集的以点分隔的路径。 该参数指示在何处可以找到匹配数据值。 如果定义了多个相关令牌,还必须指定令牌 Name 命名参数。
[CorrelationParameter( " MessageId " )]
public interface ICorrelation
{
[CorrelationInitializer]
void SendMessage( string MessageId);
[CorrelationAlias( " MessageId " , " e.MessageId " )]
event EventHandler < SendMessageArgs > MessageSended;
}
public class Correlation : ICorrelation
{
#region ICorrelation 成员
public void SendMessage( string MessageId)
{
Guid i = WorkflowEnvironment.WorkflowInstanceId;
Console.Write(i);
if (MessageSended != null )
{
MessageSended( null , new SendMessageArgs(i,MessageId));
}
}
public event EventHandler < SendMessageArgs > MessageSended;
#endregion
}
[Serializable]
public class SendMessageArgs : ExternalDataEventArgs
{
public SendMessageArgs(Guid instanceId, string messageId)
: base (instanceId)
{
this .messageId = messageId;
}
private string messageId;
public string MessageId
{
get { return messageId; }
set { messageId = value; }
}
}