• 通过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=================");

    }

     

    运行结果

    正常顺序

     

     

    提前提交

     

     

     

     

     

     

  • 相关阅读:
    区间dp_学习笔记
    状态压缩dp_学习笔记
    第十一届蓝桥杯C/C++ J题网络分析(带权并查集水题)
    状态机dp学习笔记_AcWing
    洛谷P4052 [JSOI2007]文本生成器(AC自动机+DP)
    洛谷P5840 [COCI2015]Divljak (AC自动机+fail树上dfs序+树上差分线段树维护)
    洛谷P3401 [USACO12JAN]Video Game G(AC自动机+记忆化搜索)
    HDU3613 Best Reward (exKMP/manacher)
    洛谷P2375 [NOI2014]动物园(KMP+倍增优化)
    ICPC2017南宁站题解(A,E,F,H,I,J,L,M)
  • 原文地址:https://www.cnblogs.com/foundation/p/1223520.html
Copyright © 2020-2023  润新知