本地服务是您定义并从主机添加到工作流运行时的一个类,它可以被您的宿主代码、工作流或您的活动所利用。只要宿主应用程序处于运行状态,本地服务就能够维护事件处理程序或其他侦听程序,从而可通过将消息加入队列来确保相应的数据到达工作流。您传递给本地服务的信息应包括队列名和工作流实例 ID 的相关信息,以及该服务发起工作或向您的活动返回结果时所需的任何信息。
RequestResponseData.cs <!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->using System; using System.ComponentModel; using System.ComponentModel.Design; using System.Collections; using System.Drawing; using System.Linq; using System.Workflow.ComponentModel; using System.Workflow.ComponentModel.Design; using System.Workflow.ComponentModel.Compiler; using System.Workflow.ComponentModel.Serialization; using System.Workflow.Runtime; using System.Workflow.Activities; using System.Workflow.Activities.Rules; using System.Collections.Generic; namespace CaryQueue { [Designer(typeof(SequentialActivityDesigner),typeof(IDesigner))] publicpartialclass RequestResponseData: SequenceActivity,IActivityEventListener<QueueEventArgs>,IEventActivity { public RequestResponseData() { InitializeComponent(); } Properties#region Properties publicstatic DependencyProperty OutputValuesProperty = System.Workflow.ComponentModel.DependencyProperty.Register("OutputValues", typeof(Dictionary<string, string>), typeof(RequestResponseData)); [Description("The values to be sent back to the host")] [Category("Data")] [Browsable(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public Dictionary<string, string> OutputValues { get { return ((Dictionary<string, string>)(base.GetValue(RequestResponseData.OutputValuesProperty))); } set { base.SetValue(RequestResponseData.OutputValuesProperty, value); } } publicstatic DependencyProperty InputValuesProperty = System.Workflow.ComponentModel.DependencyProperty.Register("InputValues", typeof(Dictionary<string, string>), typeof(RequestResponseData)); [Description("The data sent to the activity")] [Category("Data")] [Browsable(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public Dictionary<string, string> InputValues { get { return ((Dictionary<string, string>)(base.GetValue(RequestResponseData.InputValuesProperty))); } set { base.SetValue(RequestResponseData.InputValuesProperty, value); } } #endregion protectedoverride ActivityExecutionStatus Execute(ActivityExecutionContext executionContext) { if (ProcessMessage(GetQueue(executionContext, QueueName))) { //let the base class run the children, and return status returnbase.Execute(executionContext); } //if no items are there, then subscribe to get notified when they arrive Subscribe(executionContext, this); return ActivityExecutionStatus.Executing; } IEvent and IActivityListener#region IEvent and IActivityListener [Browsable(false)] public IComparable QueueName { get{ return"CaryQueue"; } } publicvoid Subscribe(ActivityExecutionContext parentContext, IActivityEventListener<QueueEventArgs> parentEventHandler) { WorkflowQueue queue = parentContext.GetService<WorkflowQueuingService>().CreateWorkflowQueue(QueueName, false); queue.RegisterForQueueItemAvailable(parentEventHandler); } publicvoid Unsubscribe(ActivityExecutionContext parentContext, IActivityEventListener<QueueEventArgs> parentEventHandler) { WorkflowQueue q = GetQueue(parentContext, QueueName); if (q !=null) { q.UnregisterForQueueItemAvailable(parentEventHandler); parentContext.GetService<WorkflowQueuingService>().DeleteWorkflowQueue(QueueName); } } publicvoid OnEvent(object sender, QueueEventArgs e) { ActivityExecutionContext ctx = sender as ActivityExecutionContext; if (ProcessMessage(GetQueue(ctx, e.QueueName))) { if (base.Execute(ctx) == ActivityExecutionStatus.Closed) ctx.CloseActivity(); } } #endregion private WorkflowQueue GetQueue(ActivityExecutionContext context, IComparable queueName) { WorkflowQueuingService qService = context.GetService<WorkflowQueuingService>(); if (qService !=null&& qService.Exists(queueName)) return qService.GetWorkflowQueue(queueName); else returnnull; } privatebool ProcessMessage(WorkflowQueue queue) { if (queue ==null|| queue.Count ==0) returnfalse; MessageHelper msg = queue.Peek() as MessageHelper; if (msg !=null&& msg.InputValues !=null) { InputValues = msg.InputValues; Console.WriteLine("Request:"+msg.InputValues["inputvalueone"]); Console.WriteLine("Request:"+ msg.InputValues["inputvaluetwo"]); returntrue; } returnfalse; } /**////<summary> /// Called when the base class completes executing the /// child activities. Here we know all the children are complete. ///</summary> ///<param name="executionContext"></param> protectedoverridevoid OnSequenceComplete(ActivityExecutionContext executionContext) { //pull the message from the queue and send the //response back to the host, signalling we are done. WorkflowQueue q = executionContext.GetService<WorkflowQueuingService>().GetWorkflowQueue(QueueName); MessageHelper msg = q.Dequeue() as MessageHelper; msg.SendResponse(OutputValues); //clean up, we