目录{A}微软的Windows Communication Foundation(WCF)中的Windows Workflow Foundation(WF)技术没有接收事件消息的自定义活动基于映射接口之间的WCF和工作流技术的合同事务支持声明方式编程没有要求建立一个本地服务空工作流本地服务相关事件NULL WCF服务在操作调用前/后处理能力工作与工作流本地服务并排(ExternalDataExchangeService)
微软的WF技术使人们有可能通过一个紧耦合的本地服务层接收外部(主机)事件。这一层简化的工作流程和主机应用程序的基础上的委托/事件模式之间的连接。所有这一切神奇的管道是隐蔽ExternalDataExchangeService类截获本地服务和特定的工作流队列生成一个事件消息。
为了接收由事件驱动的活动的事件消息,ExternalDataExchange接口契约必须声明与应用程序特定的事件处理程序。
事件委托有一个标准NET签名显示在下面的行。 public void EventHandler(object sender, ExternalDataEventArgs eventArgs);
的EventArgs INSTANCEID,标识,应用程序特定的数据,等如工作流事件的兴趣
接口契约元数据是用来创造一个独特的工作流队列接口类型,事件的名称,并收集相关作为一个额外的选项模式的属性。请注意,工作流队列的消息是在主机应用程序可以谈工作流的唯一途径。
从连接点的看法,工作流事件接收器和WCF客户端的事件源(用户利益)。下面的图片显示了这个逻辑的模式:
{S0}
在事件源方面,我们可以创建多种模式(如Remoting中,WSE,WCF等)生成的事件消息,并将其发送到本地或远程工作流队列。
本文介绍如何使用WCF范式的基础上,每年年底端定义在不同的接口合约,可以实现连接。你会看到事件源可以是逻辑(声明的)与事件接收器元数据相连。
下面的图片显示了一个代表性的WCF事件源和WF事件接收器之间的松耦合连接:
注意,工作流方面并不需要有本地服务层,以产生一个事件消息。对于这个WCF / WF水暖,我们只需要元数据接口的合同和操作的一个通用的装饰当然,为了使所有法术的工作。
服务操作的合同可以被映射到具体的WF的接口合同中明确说明了使用WorkflowFireEventAttribute。此属性的背后,是一个管道代码生成一个事件消息发送到工作流队列。
使用WCF的连接提供一个事件消息的工作流事件接收器(如HandleExternalEventActivity),使建设与能力上的地址,绑定和合同为基础的WCF范例的应用程序模型。例如:交付事件消息netMsmgBinding约束力的异步和断开的方式或AJAX / JSON(Orcas的CTP版)带动了浏览器的事件消息交付启用一个连接的WebHttpBinding约束力。
让我们来看看详细的WCF / WF水暖是如何做工作流队列调度的事件消息。我将假定您熟悉这些技术。此外,我前面提到的,工作流方面不使用任何此管道的自定义活动,所以它是一个标准的工作流定义(顺序或状态机)使用HandleExternalEventActivity。因此,我将集中于管道的概念和实施。
松散耦合的WCF / WF工作流事件消息发送连接的概念是基于拦截服务经营合同,将其映射到具体ExternalDataExchange界面合同(见上面的图片)(WorkflowFireEventAttribute)。
WCF服务托管在同一个WorkflowRuntime的相同的AppDomain。基本上,我们需要创建一个空的服务,我们的WCF接口契约所得。下面是一个简单的空服务和接口契约的例子:{C}
在向上的AppDomain启动,WorkflowFireEventAttribute将插入一个WorkflowFireEventOperationInvoker的OperationInvoker拦截调用服务方法之前调用。下面的代码片段显示了一个方法,它是将派遣一个工作流的事件消息:object IOperationInvoker.Invoke(object instance, object[] inputs,
out object[] outputs)
{
object retVal = null;
outputs = new object[0];
// validation for mandatory inputs
if (inputs.Length < 2 ||
!typeof(ExternalDataEventArgs).IsInstanceOfType(inputs[1]))
throw new InvalidOperationException(string.Format(" ... ");
// mandatory inputs
object sender = inputs[0];
ExternalDataEventArgs eventArgs = inputs[1] as ExternalDataEventArgs;
if (Transaction.Current != null &&
Transaction.Current.TransactionInformation.Status ==
TransactionStatus.Active)
{
WorkflowInstance workflowInstance = null;
eventArgs.WaitForIdle = false;
#region action - transactional delivery to the workflow queue
using(TransactionScope ts =
new TransactionScope(TransactionScopeOption.RequiresNew))
{
// pre-processing
if (this.Option == WorkflowFireEventOption.After)
{
retVal = this._innerOperationInvoker.Invoke(instance, inputs,
out outputs);
}
// fire event
workflowInstance =
WorkflowHelper.DispatchEvent(this.EventType,this.EventName,
sender,eventArgs,true);
// storing a workflow into the database
workflowInstance.Unload();
// post-process
if (this.Option == WorkflowFireEventOption.Before)
{
retVal = this._innerOperationInvoker.Invoke(instance, inputs,
out outputs);
}
// done
ts.Complete();
}
try
{
// workaround to detect WorkflowStatus
workflowInstance.Start();
}
catch (Exception ex)
{
// WorkflowStatus != Created (therefore we can go ahead and use it)
Trace.WriteLine(ex.Message);
}
#endregion
}
else
{
#region action - non-transactional delivery to the workflow queue
// pre-processing
if (this.Option == WorkflowFireEventOption.After)
{
retVal = this._innerOperationInvoker.Invoke(instance, inputs, out outputs);
}
// dispatching event
WorkflowHelper.DispatchEvent(this.EventType, this.EventName,
sender, eventArgs);
// post-processing
if (this.Option == WorkflowFireEventOption.Before)
{
retVal = this._innerOperationInvoker.Invoke(instance, inputs, out outputs);
}
#endregion
}
return retVal;
}
基本上,该方法是分为3部分,如前处理,调度和后处理基础上的选项和事务上下文调用。选项可以为特定应用的逻辑,例如,创建工作流,填充的EventArgs属性,默认选项是"无。在呼叫其他分机使用强制性的参数,如输入[0]和投入[1]或输出背后的其他方法的参数。这些扩展应用程序的特定功能。在事务上下文的射击事件
事务的方式提供一个事件消息的工作流实例是有点不同的事务上下文驱动的其他资源。目前,我们没有一个工作流实例的事务的内存资源,因此ACID事务间接通过SqlWorkflowPersistenceService。这个概念是基于工作流实例发送的事件消息,在同步方式(WaitForIdle = FALSE)和脱水的交易范围内的工作流程,然后一直致力于在交易后,工作流返回到内存(补水) 。出于这个原因,我们要创建一个新的事务上下文来避免死锁。请注意,根据新的交易背景和他们的逻辑运行的预/后处理可以参加ACID事务。
让我们继续与调用dispatchEvent调用。此方法用于创建和启动工作流实例的基础上的eventArgs.InstanceId值,调用的辅助SendEventMessage方法来生成一个工作流程事件消息,并把它发送到实例队列。以下是dispatchEvent方法的代码片段:public static WorkflowInstance DispatchEvent(Type interfaceType,
string eventName, object sender, ExternalDataEventArgs eventArgs)
{
// input arguments validation
if (interfaceType == null)
throw new ArgumentNullException("interfaceType");
if (string.IsNullOrEmpty(eventName))
throw new ArgumentException("eventName");
if (eventArgs == null)
throw new ArgumentNullException("eventArgs");
// Find the custom WCF Extension on the Service Host by it's type
WFServiceHostExtension extension =
OperationContext.Current.Host.Extensions.Find<WFServiceHostExtension>();
// Get a reference to the WorkflowRuntime
WorkflowRuntime workflowRuntime = extension.WorkflowRuntime;
// get instance of the workflow
WorkflowInstance instance = workflowRuntime.GetWorkflow(eventArgs.InstanceId);
if (!bTransactional)
{
try
{
// workaround to detect WorkflowStatus
instance.Start();
}
catch (Exception ex)
{
// WorkflowStatus != Created (therefore we can go ahead and use it)
Trace.WriteLine(ex.Message);
}
}
//WorkflowMessageEventHandler2 handler2 =
// new WorkflowMessageEventHandler2(interfaceType, eventName, instance);
//handler2.EventHandler(sender, eventArgs);
SendEventMessage(interfaceType, eventName, sender, eventArgs, instance);
return instance;
}
请注意,这将是很好System.Workflow.Activities命名空间,这将大大简化了这一实施公共WorkflowMessageEventHandler类。我为此创建 - 看到helpers.cs文件,但它并不在交易范围内的工作(我会弄清楚这个问题,并更新)。现在,我们可以使用反射来调用内部类的公共方法,因为它是在下面的代码片段所示:
WorkflowFireEventAttributeprivate static void SendEventMessage(Type interfaceType, string eventName,
object sender, ExternalDataEventArgs eventArgs, WorkflowInstance instance)
{
// get the type class
Type type =
Type.GetType("System.Workflow.Activities.WorkflowMessageEventHandler, ...");
// create instance
object[] args1 =
new object[3] {eventType, eventType.GetEvent(eventName), instance.WorkflowRuntime};
object handler = Activator.CreateInstance(type, bindingAttr1, null, args1, cultureInfo);
// invoke method
object args2 = new object[2] { sender, eventArgs };
type.InvokeMember("EventHandler", bindingAttr2, null, handler, args2);
}
这是一个管道类在经营合同中插入一个自定义调用执行调度事件消息从WCF的WF范例以松散耦合的方式。
WorkflowFireEventAttribute类可以发起以下属性:事件类型 - 类型ExternalDataExchange(强制性财产)归因于工作流界面EventName - 工作流事件的名称(默认事件的名称是经营合同的名称)WorkflowFireEventOption - 选项的操作调用前或后过程中的服务方法没有 - 没有服务方法调用(默认选项)前 - 工作流事件是发射前的服务方法调用烧制后的服务方法已被调用工作流事件后 -
使用上述物业在下面的例子所示,其中IFireEventTest接口映射到两个有相同的事件名工作流接口:[ServiceBehavior]
public class ServiceTest1 : IFireEventTest
{
[WorkflowFireEvent(EventType = typeof(IWorkflowSimpleEvents))]
public void Approve(object sender, ExternalDataEventArgs e) { }
[WorkflowFireEvent(EventType = typeof(IWorkflowEvents))]
public void Reject(object sender, MyEventArgs e) { }
[WorkflowFireEvent(EventName = "Reject", EventType =
typeof(IMyWorkflowEvents))]
public void MyReject(object sender, MyEventArgs e) { }
}
或在未来样本所示,我们可以如何处理调度范围内的操作方法或处理前发射工作流程事件的事件消息:[ServiceBehavior]
public class ServiceTest2 : IFireEventTest
{
public void Approve(object sender, ExternalDataEventArgs e,
string workflowType)
{
// for test purpose
MyObject mo = e.WorkItem as MyObject;
Console.WriteLine("Operation Approve - {0}", mo.Name);
// deliver message to the workflow instance
WorkflowHelper.DispatchEvent(typeof(IWorkflowSimpleEvents),
"Approve", sender, e);
}
[WorkflowFireEvent(Option = WorkflowFireEventOption.After,
EventName = "Reject", EventType = typeof(IWorkflowEvents))]
public void Reject(object sender, MyEventArgs e)
{
// for test purpose
Console.WriteLine("Operation Reject - {0}", e.TaskName);
}
}
正如我刚才所说,WCF连接使之间的任何事件源(客户端)和服务的结合使用。下面的代码片段显示了一个服务端点配置config文件的例子:
相关事件<service name="ServiceHost.ServiceTest1">
<endpoint
address="net.tcp://localhost:11111/Workflow"
binding="netTcpBinding"
contract="InterfaceContract.IFireEventTest"/>
</service>
<service name="ServiceHost.ServiceTest3">
<endpoint
address="net.msmq://localhost/private/rk.workflow_test"
binding="netMsmqBinding"
bindingConfiguration="PoisonBinding"
contract="InterfaceContract.IFireEventTest"/>
</service>
在使用相同的接口合约,事件(S)驱动多个工作流事件接收器情况下,必须与一个特定的参数值,在相同的工作流实例创建一个独特的工作流队列名称。在这篇文章中描述的解决方案支持此功能,它是完全透明的工作流事件接收器HandleExternalEventActivity(HEEA)的。此功能也WorkflowMessageEventHandler2类实施。
下面的代码片段显示了一个简单的事件拒绝相关的参数taskName上:[ExternalDataExchange]
[CorrelationParameter("taskName")]
public interface IWorkflowEvents
{
[CorrelationInitializer]
void Initializer(string taskName);
[CorrelationAlias("taskName", "TaskName")]
event EventHandler<MyEventArgs> Reject;
}
相关事件需要有本地服务层执行CorrelationInitializer归因方法。此方法必须在特定的逻辑相关标记范围内调用本地服务HEEA事先告知相关值。public class MyLocalService : IWorkflowEvents
{
public void Initializer(string taskName)
{
Console.WriteLine("Initializer - {0}", taskName);
}
public event EventHandler<MyEventArgs> Reject;
}
请注意,在我们的松耦合连接,相关值可以被发送的事件源,也可以在WCF服务的操作方法前处理。附加的WorkflowRuntime
在WorkflowRuntime可以连接到WCF服务主机通过它的扩展。对于这种情况,我已经创建了两个构造一个WSServiceHostExtension类。第一个,将存储现有的WorkflowRuntime参考(例如:由Orcas中WorkflowServices创建),第二个会从配置文件中创建一个WorkflowRuntime的。
下面的代码片段显示了一个创建WorkflowRuntime的基础上的配置文件,并将其附加到WCF主机的例子:using (System.ServiceModel.ServiceHost host =
new System.ServiceModel.ServiceHost(typeof(ServiceTest3)))
{
// Service extension for WF
WFServiceHostExtension extension =
new WFServiceHostExtension("WorkflowRuntimeConfig");
// Add the Extension to the ServiceHost collection
host.Extensions.Add(extension);
host.Open();
Console.WriteLine("Press any key to stop server...");
Console.ReadLine();
host.Close();
}
工作流运行时配置的范例:
请注意,SqlWorkflowPersistenceService必须被包括在配置文件中。
FireWorkflowEvent解决方案分为两个文件夹,如WorkflowEventService - 托管的实施和WorkflowFireEventAttribute。此程序集必须包含托管WCF和WF的应用程序的AppDomain。测试的目的只是为了证明使用WorkflowFireEventAttribute其他文件夹。此文件夹包含几个项目 - 3的工作流程WorkflowLibrary(如ConsoleApplications生成一个事件,InterfaceContracts WCF和WF,WCF消息控制台上的简单的日志记录,ServiceHost的项目承载WCF服务和WorkflowRuntime的最后一个项目记录仪状态机,顺序和XOML激活)。
让我们开始测试。我认为您的环境netfx 3.0和SQLEXPRESS安装,包括一个工作流的东西。测试1。可拆卸事务事件
此测试演示通过事务性MSMQ事件源和事件接收器(WCF - 工作流程)之间的连接。从年底交付的事件消息,结束事务(可拆卸)的方式,使建设强大的事件驱动的体系结构。
以下是如何下探WCF和WF模型的主要步骤:第1步。工作流程
在这一步,我们需要创建一个EventHandler的方法(S)接口ExternalDataExchange合同。在我们的例子测试中,有简单的事件,批准工作流ExternalDataEventArgs。一旦我们有了这份合同,如HandleExternalEventActivity(HEEA)的事件接收器可以转让的。请注意,这是没有必要创建一个本地服务的实施。
下图显示了这些步骤 - 界面合同,HEEA物业和测试工作流程:
{S4}的
的所有工作流。下面的步骤是WCF只。第2步。 WCF服务
首先,我们需要创建一个服务(接口)合同消耗流事件(S)。下面的代码片段显示了一个简单的合同耗时两个事件 - 拒绝批准。在这个测试中,只批准活动将于火。[ServiceContract]
public interface IFireEventTest
{
[OperationContract(IsOneWay = true)]
void Reject(object sender, MyEventArgs e);
[OperationContract(IsOneWay = true)]
void Approve(object sender, ExternalDataEventArgs e);
}
现在,我们可以创建一个服务和装饰为特定的事件与工作流程的整合。在这个测试中,我们要求事件后处理(触发事件前,看到选项)和IWorkflowSimpleEvents合同水暖操作调用。操作设置事务处理,自动犯。[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class ServiceTest3 : IFireEventTest
{
[WorkflowFireEvent(Option = WorkflowFireEventOption.Before,
EventType = typeof(IWorkflowSimpleEvents))]
[OperationBehavior(TransactionAutoComplete =
true, TransactionScopeRequired = true)]
public void Approve(object sender, ExternalDataEventArgs e)
{
/*
if(MessageBox.Show("Abort ...", "Approve", MessageBoxButtons.YesNo)==
DialogResult.Yes)
{
throw new Exception("Transaction has been aborted manually");
}
*/
}
[WorkflowFireEvent(EventType = typeof(IWorkflowEvents))]
public void Reject(object sender, MyEventArgs e) { }
}
主办这次在AppDomain中的服务之前,我们要创建一个服务的配置节。下面的代码片段显示ServiceHost.exe.config端点和NetMsmqBinding的文件的一部分。<services>
<service name="ServiceHost.ServiceTest3">
<endpoint
address="net.msmq://localhost/private/rk.workflow_test"
binding="netMsmqBinding"
bindingConfiguration="PoisonBinding"
contract="InterfaceContract.IFireEventTest"/>
</service>
</services>
<bindings>
<netMsmqBinding>
<binding name="PoisonBinding"
receiveErrorHandling="Drop"
receiveRetryCount="0"
exactlyOnce="true"
useSourceJournal="true"
useActiveDirectory="false">
<security mode="None" />
</binding>
</netMsmqBinding>
</bindings>
现在,我们可以承载在AppDomain中的上述服务 - ServiceHost的项目,Program.cs文件。之后,我们的工作流程已通过WCF服务公开获得核准事件消息。第3步。 WCF客户端
这一步,显示了一个例子,如何在客户端产生的交易方式批准事件。出于测试目的,workflow2.xoml是建立和坚持在射击事件之前。剩下的工作是直接的,如创建FireWorkflowEvent配置,应用程序的特定事件感兴趣的事件参数的通道和发送审批消息。请注意,将消息发送到MSMQ队列时,交易范围是致力。using (TransactionScope ts =
new TransactionScope(TransactionScopeOption.RequiresNew))
{
// unload workflow (for test purpose)
using(XmlReader xmlReader=
XmlReader.Create(@"..\..\..\WorkflowLibrary\Workflow2.xoml"))
{
wi = wr.CreateWorkflow(xmlReader);
}
wi.Unload();
using (ChannelFactory<IFireEventTest> factory =
new ChannelFactory<IFireEventTest>("FireWorkflowEvent"))
{
IFireEventTest channel = factory.CreateChannel();
// eventArgs
ExternalDataEventArgs eventArgs =
new ExternalDataEventArgs(wi.InstanceId);
eventArgs.WaitForIdle = false;
eventArgs.WorkItem = MyObject.Create(sender, ii);
// fire workflow event
channel.Approve(sender, eventArgs);
// close this channel
factory.Close();
}
ts.Complete();
}
现在,我们已经准备好作出实际的测试。第4步。运行测试
启动ConsoleApplication2方案。下面的屏幕片段展示了一个创建和装卸Workflow2过程中。使用包括记录器,在控制台屏幕上会显示一个事件消息发送到WCF服务的信封(和转发工作流程)。
{五}
启动ServiceHost的程序之前,消息可检查私人rk.workflow_test队列。我们没有约束力设置一个超时交付和接受服务的消息,因此,我们可以随时启动的服务。
下面的图片显示控制台屏幕片段ServiceHost的方案。我们可以看到在这台主机是多少端点,接收事件消息,以及如何此消息通过Workflow2。基于工作流定义,工作流会收到此消息后完成。
测试可重复另一个工作流实例ConsoleApplication2屏幕上按任意键。
{中六}
一件事。在第2步,我们都谈到了射击事件后处理。让我们的注释和运行服务的主机更多的时间。每个批准的事件调用将被打断的交易范围内的下列对话:
{七}
根据你的选择,我们可以模拟中止情景。请注意,消息是从MSMQ队列下降,但NetMsmqBinding的,如果你是在Vista上运行,可以使用毒药队列的重新配置。
此测试,让我们来看看的WorkflowFireEventAttribute另一个例子。测试2。触发相关事件
此测试演示一个相关的相关参数是taskName拒绝事件。每个工作流相关的范围有责任等待拒绝事件之前初始化参数。为此,工作流调用的CallExternalMethodActivity和相关参数的初始化值传递到主机应用程序,因此必须创建本地服务,并登记在WorkflowRuntime。
{S8}
{S9}
为了测试这种情况下,ServiceHost的程序必须ConsoleApplication1方案之前推出。请注意,本次测试使用应用程序的特定MyEventArgs从ExternalDataEventArgs衍生事件消息,因此,我们必须添加到LT这种类型; system.runtime.serializationgt;为配置文件(服务和客户端)的部分:<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
<add type="System.Workflow.Activities.ExternalDataEventArgs,
System.Workflow.Activities,
Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<knownType type ="InterfaceContract.MyObject, InterfaceContract"/>
</add>
<add type="InterfaceContract.MyEventArgs, InterfaceContract">
<knownType type ="InterfaceContract.MyObject, InterfaceContract"/>
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>
让我们做的StateMachine工作流的测试。测试3。射击简单的状态机事件
下面的图片显示了一个国家的国家机器简单的例子,等待超时限制内批准事件。传入的批准事件将回收的状态,并重新引发超时限制。
{S10}
{S11}
{S12}
接口合同是非常简单的要求只有一个Null(无体)WCF服务。
为了测试这种情况下,ServiceHost的程序必须ConsoleApplication方案之前推出。
注意,测试ServiceHost的程序被配置为运行所有测试客户端控制台程序,因此它可以运行一个无限循环的测试。通用WCF服务
通用服务的目的是主机与一个典型的事件,如发件人和ExternalDataEventArgs参数签名简单事件的普遍服务。通过WorkItem的财产ExternalDataEventArgs对象工作流应用程序的特定对象可以被传递。
下面的代码片段显示了通用露出通过WCF工作流服务的完整的实施:[ServiceContract]
public interface IFireWorkflowEvent
{
[OperationContract(Action = "*", IsOneWay = true)]
void FireWorkflowEvent(Message message);
}
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class WorkflowEventService : IFireWorkflowEvent
{
public void FireWorkflowEvent(Message message)
{
WorkflowHelper.FireEvent(message);
}
}
正如你可以看到,没有任何操作拦截器和映射接口合约WorkflowFireEventAttribute。基于隐式映射一个SOAP消息由事件和接口类型的名称定义的工作流界面合同的概念和这种解决方案的限制。经营合同的名称可以很容易地映射到工作流事件的名称。事件类型,如第二个映射要求并不简单。我决定现在使用WCF接口契约的命名空间。
OK,现在我们可以看看该WorkflowHelper.FireEvent如何将传入消息映射到工作流:public static void FireEvent(Message message)
{
System.Xml.XmlDictionaryReader reader = message.GetReaderAtBodyContents();
// event contract
Type interfaceType = Type.GetType(reader.NamespaceURI);
string eventName = reader.Name;
// body of the event message
reader.ReadStartElement();
string sender = reader.ReadElementContentAsString("sender",
reader.NamespaceURI);
DataContractSerializer xs =
new DataContractSerializer(typeof(ExternalDataEventArgs),
"e", reader.NamespaceURI);
ExternalDataEventArgs eventArgs =
(ExternalDataEventArgs)xs.ReadObject(reader);
while (reader.NodeType != XmlNodeType.EndElement) { reader.Read(); }
reader.ReadEndElement();
// deliver message to the workflow queue
DispatchEvent(interfaceType, eventName, sender, eventArgs);
}
FireEvent方法反序列化消息体获得前两个EventHandler的参数,如发件人和E.事件的合同,因为我上面提到的,是从方法的名称和命名空间。这些参数的dispatchEvent被称为派遣一个事件消息,以同样的方式,因为它已被前面所述的工作流队列。下面的代码片段显示了这个通用的WCF服务WCF接口契约的例子:[ServiceContract(Namespace="InterfaceContract.IWorkflowSimpleEvents,
InterfaceContract")]
public interface IFireEventTest2
{
[OperationContract(IsOneWay = true)]
void Approve(object sender, ExternalDataEventArgs e);
}
它是如何工作?
好了,之后一直在用的WorkflowRuntime的AppDomain中的WorkflowEventService托管,我们正在准备接收一个通过终点的事件消息。下面的配置片段显示这个通用的配置。当然,我们可以创建许多类型的绑定:
因此,客户端(如ConsoleApplication)将发送的事件消息基于WCF接口契约(如IFireEventTest2)以上的端点,转发到通用服务(行动="*")的运作FireWorkflowEvent。一旦我们有了一个方法的消息,我们的过程作为一个事件消息,否则将抛出一个异常。状态机中的相关事件
在多个事件驱动的活动(HEEA)时,等候在同一国家的同一事件的情况下,相关的功能可以帮助它。下图显示了相关参数,可以在初始化StateInitializationActivity。我并没有包括这个测试,因此这种情况下,尝试修改Workflow1与ConsoleApplication1程序对其进行测试。
{S13}
这篇文章描述了一个WCF / WF集成发射工作流事件。这个概念是基于WCF和WF界面合同之间的松耦合的连接。这是一个简单,透明的一体化,没有要求修改工作流和建设没有相关事件的一个自定义的本地服务。