通过AEC解读WF的核心原理(十二)WorkflowQueue的提前提交
说明
WF作为一种以交互式开发与流程控制为基础的SDK,实例内部与外部的通信是由WorkflowQueuingService完成的,
WorkflowQueuingService维护了一个Queue,实例向WorkflowQueuingService添加Queue(CreateWorkflowQueue方法),并定阅 QueueItemAvailable事件,外部通过EnqueueItem方法将消息发送到指定工作流队列。
WorkflowQueuingService的使用我在前面的例子中已多次使用。
本例是一个提前提交队列消息的实现:
[A挂起] -> [B挂起] -> [C挂起]
当流程运行到[A挂起],提交[A挂起],将进入[B挂起],提交[B挂起],将进入[C挂起]
本例可以在运行到[A挂起]时,先提交[B挂起],遭提交[A挂起],这样流程运行完[A挂起]后,在[B挂起]不会等待,将直接运行完[B挂起],将进入[C挂起]
例子:https://files.cnblogs.com/wxwinter/aec12.rar
例子
[5012提前提交]
通信接口
public interface 通信接口 { string Text { set; get; } IComparable QueueName { set; get; } } |
public class 通信类 : WorkflowRuntimeService, 通信接口 { public string Text { set; get; }
public IComparable QueueName { set; get; }
public void NextStep(Guid instanceID, object inputData) { WorkflowInstance instance = Runtime.GetWorkflow(instanceID); instance.EnqueueItemOnIdle(QueueName, inputData, null, null); } public void NextStep(Guid instanceID, object inputData,string qn) { WorkflowInstance instance = Runtime.GetWorkflow(instanceID); instance.EnqueueItemOnIdle(qn, inputData, null, null); } } |
等待触发Activity
public class 等待触发 : Activity, IActivityEventListener<QueueEventArgs>, IEventActivity {
public string Text { set; get; }
protected override void Initialize(IServiceProvider provider) { System.Console.WriteLine(this.Name + ":进入队列(Initialize)");
WorkflowQueuingService queueService = provider.GetService(typeof(WorkflowQueuingService)) as WorkflowQueuingService;
WorkflowQueue queue = queueService.CreateWorkflowQueue(this.QueueName, false);
通信接口 obj =provider.GetService(typeof(通信接口)) as 通信接口;
obj.QueueName = this.QueueName;
obj.Text = this.Text;
base.Initialize(provider); }
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext) { if (myProcessAEC(executionContext)) { return ActivityExecutionStatus.Closed; } else { Subscribe(executionContext, this); return ActivityExecutionStatus.Executing; } }
private bool myProcessAEC(ActivityExecutionContext provider) { WorkflowQueuingService queueService = provider.GetService<WorkflowQueuingService>(); if (queueService.Exists(this.QueueName) && queueService.GetWorkflowQueue(this.QueueName).Count > 0) { object inputData = queueService.GetWorkflowQueue(this.QueueName).Dequeue();
System.Console.WriteLine(this.Name + ":外部传入的数据:" + inputData.ToString());
通信接口 obj = provider.GetService<通信接口>();
this.Text = obj.Text; return true; } return false; }
//实现IActivityEventListener<QueueEventArgs> 的[发生订阅事件时的处理过程]事件方法
public void OnEvent(object sender, QueueEventArgs e) { ActivityExecutionContext aec = sender as ActivityExecutionContext; if (myProcessAEC(aec)) { Unsubscribe(aec, this); aec.CloseActivity(); } }
//实现IEventActivity的[WorkflowQueue名称]属性 public IComparable QueueName { get { return this.QualifiedName; } }
//实现IEventActivity的[事件的订阅]方法 public void Subscribe(ActivityExecutionContext parentContext, IActivityEventListener<QueueEventArgs> parentEventHandler) { WorkflowQueuingService queueService = parentContext.GetService(typeof(WorkflowQueuingService)) as WorkflowQueuingService;
WorkflowQueue queue = queueService.GetWorkflowQueue(this.QueueName);
queue.RegisterForQueueItemAvailable(parentEventHandler);
通信接口 obj = parentContext.GetService<通信接口>(); if (obj != null) { obj.QueueName = this.QueueName; obj.Text = this.Text; }
} //实现IEventActivity的[取消事件的订阅]方法 public void Unsubscribe(ActivityExecutionContext parentContext, IActivityEventListener<QueueEventArgs> parentEventHandler) { WorkflowQueuingService queueService = parentContext.GetService<WorkflowQueuingService>(); if (queueService != null && queueService.Exists(this.QueueName)) { queueService.GetWorkflowQueue(this.QueueName).UnregisterForQueueItemAvailable(parentEventHandler); queueService.DeleteWorkflowQueue(this.QueueName); } } } |
测试用工作流
public class Workflow1: SequentialWorkflowActivity { public Workflow1() { InitializeComponent(); }
[System.Diagnostics.DebuggerNonUserCode] private void InitializeComponent() { this.CanModifyActivities = true; this.b = new wxwinterAecTest.等待触发(); this.codeActivity1 = new System.Workflow.Activities.CodeActivity(); this.a = new wxwinterAecTest.等待触发(); // // b // this.b.Name = "b"; this.b.Text = null; // // codeActivity1 // this.codeActivity1.Name = "codeActivity1"; this.codeActivity1.ExecuteCode += new System.EventHandler(this.codeActivity1_ExecuteCode); // // a // this.a.Name = "a"; this.a.Text = null; // // Workflow1 // this.Activities.Add(this.a); this.Activities.Add(this.codeActivity1); this.Activities.Add(this.b); this.Name = "Workflow1"; this.CanModifyActivities = false;
}
private 等待触发 b; private CodeActivity codeActivity1; private 等待触发 a; private void codeActivity1_ExecuteCode(object sender, EventArgs e) { System.Console.WriteLine("codeActivity1"); } } |
宿主
WorkflowRuntime workflowRuntime = new WorkflowRuntime(); 通信类 obj = new 通信类(); WorkflowInstance instance;
private void Form1_Load(object sender, EventArgs e) { workflowRuntime.AddService(obj);
workflowRuntime.WorkflowCompleted += new EventHandler<WorkflowCompletedEventArgs>(workflowRuntime_WorkflowCompleted); workflowRuntime.WorkflowTerminated += new EventHandler<WorkflowTerminatedEventArgs>(workflowRuntime_WorkflowTerminated); workflowRuntime.WorkflowIdled += new EventHandler<WorkflowEventArgs>(workflowRuntime_WorkflowIdled);
} //启动流程 private void button1_Click(object sender, EventArgs e) { instance = workflowRuntime.CreateWorkflow(typeof(Workflow1)); instance.Start();
}
//操作 private void button2_Click(object sender, EventArgs e) {
obj.NextStep(instance.InstanceId, this.textBox1.Text, textBox2.Text); }
static void workflowRuntime_WorkflowIdled(object sender, WorkflowEventArgs e) { System.Console.WriteLine("--------------------WorkflowIdled------------------");
}
static void workflowRuntime_WorkflowTerminated(object sender, WorkflowTerminatedEventArgs e) { System.Console.WriteLine("Terminated" + e.Exception.Message); }
static void workflowRuntime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e) { System.Console.WriteLine("===================WorkflowCompleted================="); } |
运行结果
正常顺序
|
提前提交
|