⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 statemachine.cs

📁 WF本质论一书的源码,要书籍的朋友同我联系.
💻 CS
字号:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime;

namespace EssentialWF.Activities
{
  public class Arc { }
  public class StateMachineAction { }
  public class StateMachine : CompositeActivity
  {
    public StateMachine()
      : base()
    {
      base.SetReadOnlyPropertyValue(StatesProperty,
        new List<string>());

      base.SetReadOnlyPropertyValue(ArcsProperty,
        new List<Arc>());
    }

    public static readonly DependencyProperty
      StatesProperty = DependencyProperty.Register(
        "States",
        typeof(List<string>),
        typeof(StateMachine),
        new PropertyMetadata(DependencyPropertyOptions.Metadata
          | DependencyPropertyOptions.ReadOnly,
          new Attribute[] { 
            new DesignerSerializationVisibilityAttribute(
              DesignerSerializationVisibility.Content) }
        )
      );

    public static readonly DependencyProperty
      ArcsProperty = DependencyProperty.Register(
        "Arcs",
        typeof(List<Arc>),
        typeof(StateMachine),
        new PropertyMetadata(DependencyPropertyOptions.Metadata 
          | DependencyPropertyOptions.ReadOnly,
          new Attribute[] { 
            new DesignerSerializationVisibilityAttribute(
              DesignerSerializationVisibility.Content) }
        )
      );

    [DesignerSerializationVisibility(
      DesignerSerializationVisibility.Content)]
    public List<string> States
    {
      get { return GetValue(StatesProperty) as List<string>; }
    }

    [DesignerSerializationVisibility(
      DesignerSerializationVisibility.Content)]
    public List<Arc> Arcs
    {
      get { return GetValue(ArcsProperty) as List<Arc>; }
    }

    private string currentState;
    private Arc currentArc;
    private List<string> history;

    protected override void Initialize(
      IServiceProvider provider)
    {
      this.currentState = "NONE";
      this.currentArc = null;
      this.history = new List<string>();

      WorkflowQueuingService qService = 
        provider.GetService(typeof(WorkflowQueuingService)) 
          as WorkflowQueuingService;
      if (!qService.Exists(this.Name))
        qService.CreateWorkflowQueue(this.Name, false);

      base.Initialize(provider);
    }

    protected override void Uninitialize(
      IServiceProvider provider)
    {
      this.currentState = "NONE";
      this.currentArc = null;
      this.history = null;

      WorkflowQueuingService qService = 
        provider.GetService(typeof(WorkflowQueuingService))
          as WorkflowQueuingService;
      if (qService.Exists(this.Name))
        qService.DeleteWorkflowQueue(this.Name);

      base.Uninitialize(provider);
    }

    protected override ActivityExecutionStatus Execute(
      ActivityExecutionContext context)
    {
      if (EnabledActivities.Count == 0)
        return ActivityExecutionStatus.Closed; 
      
      this.currentState = "START";
      history.Add(currentState);

      WorkflowQueuingService qService = 
        context.GetService<WorkflowQueuingService>();
      WorkflowQueue queue = qService.GetWorkflowQueue(this.Name);
      queue.QueueItemAvailable += this.ResumeAt;

      return ActivityExecutionStatus.Executing;
    }

    void ResumeAt(object sender, QueueEventArgs e)
    {
      ActivityExecutionContext context = 
        sender as ActivityExecutionContext;
      WorkflowQueuingService qService = 
        context.GetService<WorkflowQueuingService>();
      WorkflowQueue queue = qService.GetWorkflowQueue(this.Name);

      object obj = queue.Dequeue();
      StateMachineAction action = obj as StateMachineAction;

      if (action != null)
      {
        if (currentArc != null)
        {
          // state transition in progress
          Console.WriteLine("action rejected");
          return;
        }

        Arc proposed = null;
        foreach (Arc arc in this.Arcs)
        {
          // Find the right arc
          if (arc.ActivityName.Equals(action.ActivityName)
            && arc.From.Equals(this.currentState))
          {
            proposed = arc;
            break;
          }
        }

        if (proposed == null)
        {
          Console.WriteLine("action not valid: " + action.ActivityName);
          return;
        }

        foreach (Activity child in EnabledActivities)
        {
          if (child.Name.Equals(proposed.ActivityName))
          {
            currentArc = proposed;
            Run(context, child, proposed.InputProp, action.Input);
            return;
          }
        }
      }
      else // query
      {
        StateMachineQuery query = obj as StateMachineQuery;
        if (query != null)
        {
          Console.WriteLine("--QueryResults--");
          Console.WriteLine("Current State: " + this.currentState);
          Console.WriteLine("Current Transition: " +
            ((currentArc == null) ? "-none-" : 
           (currentArc.ActivityName + "<" + 
            currentArc.From + "," + currentArc.To + ">"))
          );
          Console.Write("History: ");
          foreach (string s in this.history)
            Console.Write(s + (s.Equals("END") ? "" : "->"));
          Console.Write("\n");
          if (currentArc == null)
          {
            Console.WriteLine("Possible Transitions:");
            foreach (Arc arc in this.Arcs)
            {
              if (arc.From.Equals(this.currentState))
                Console.WriteLine(" " + arc.ActivityName + 
                 "<" + arc.From + "," + arc.To + ">" + 
                 " Input=" + arc.InputProp);
            }
          }
        }

        else
        {
          Console.WriteLine("unrecognized input: " + obj.ToString());
        }
      }
    }

    private void Run(ActivityExecutionContext context,
      Activity child, string propName, object propValue)
    {
      ActivityExecutionContextManager manager = 
        context.ExecutionContextManager;
      ActivityExecutionContext c = 
        manager.CreateExecutionContext(child);

      // Use reflection to set the input property value
      object o = c.Activity;
      o.GetType().GetProperty(propName).GetSetMethod().
        Invoke(o, new object[] { propValue });

      c.Activity.Closed += ContinueAt;
      c.ExecuteActivity(c.Activity);
    }

    void ContinueAt(object sender,
      ActivityExecutionStatusChangedEventArgs e)
    {
      e.Activity.Closed -= this.ContinueAt;
      ActivityExecutionContext context =
        sender as ActivityExecutionContext;

      ActivityExecutionContextManager manager = 
        context.ExecutionContextManager;
      ActivityExecutionContext c = 
        manager.GetExecutionContext(e.Activity);
      manager.CompleteExecutionContext(c, false);

      currentState = this.currentArc.To;
      history.Add(currentState);
      currentArc = null;

      if (currentState.Equals("END"))
        context.CloseActivity();
    }

    // Cancellation logic
    //...
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -