工作流学习过程-状态机
[ExternalDataExchange]
public interface ICarService
{
event EventHandler<ExternalDataEventArgs> StartEngine;
event EventHandler<ExternalDataEventArgs> StopEngine;
event EventHandler<ExternalDataEventArgs> StopMovement;
event EventHandler<ExternalDataEventArgs> GoForward;
event EventHandler<ExternalDataEventArgs> GoReverse;
event EventHandler<ExternalDataEventArgs> LeaveCar;
event EventHandler<ExternalDataEventArgs> BeepHorn;
void SendMessage(string message);
}
[Serializable]
public class MessageReceivedEventArgs : ExternalDataEventArgs
{
private String message;
public MessageReceivedEventArgs(Guid instanceId, String message)
: base(instanceId)
{
this.message = message;
}
public String Message
{
get { return message; }
set { message = value; }
}
}
public class CarService : ICarService
{
public void SendMessage(string message)
{
if (MessageReceived != null)
{
MessageReceivedEventArgs args = new MessageReceivedEventArgs(WorkflowEnvironment.WorkflowInstanceId, message);
MessageReceived(this, args);
}
}
public event EventHandler<MessageReceivedEventArgs> MessageReceived;
public void OnStartEngine(ExternalDataEventArgs e)
{
if (StartEngine != null)
{
StartEngine(null, e);
}
}
public void OnStopEngine(ExternalDataEventArgs e)
{
if (StopEngine != null)
{
StopEngine(null, e);
}
}
public void OnStopMovement(ExternalDataEventArgs e)
{
if (StopMovement != null)
{
StopMovement(null, e);
}
}
public void OnGoForward(ExternalDataEventArgs e)
{
if (GoForward != null)
{
GoForward(null, e);
}
}
public void OnGoReverse(ExternalDataEventArgs e)
{
if (GoReverse != null)
{
GoReverse(null, e);
}
}
public void OnLeaveCar(ExternalDataEventArgs e)
{
if (LeaveCar != null)
{
LeaveCar(null, e);
}
}
public void OnBeepHorn(ExternalDataEventArgs e)
{
if (BeepHorn != null)
{
BeepHorn(null, e);
}
}
#region ICarService 成员
public event EventHandler<ExternalDataEventArgs> StartEngine;
public event EventHandler<ExternalDataEventArgs> StopEngine;
public event EventHandler<ExternalDataEventArgs> StopMovement;
public event EventHandler<ExternalDataEventArgs> GoForward;
public event EventHandler<ExternalDataEventArgs> GoReverse;
public event EventHandler<ExternalDataEventArgs> LeaveCar;
public event EventHandler<ExternalDataEventArgs> BeepHorn;
#endregion
public partial class Car : Form
{
WorkflowRuntimeManager manager = null;
WorkflowInstanceWrapper instanceWrapper = null;
CarService carService = null;
public Car()
{
InitializeComponent();
btnStartEngine.Tag = "StartEngine";
btnStopEngine.Tag = "StopEngine";
btnGoForward.Tag = "GoForward";
btnGoReverse.Tag = "GoReverse";
btnStopMovement.Tag = "StopMovement";
btnBeepHorn.Tag = "BeepHorn";
btnLeaveCar.Tag = "LeaveCar";
}
private void Car_Load(object sender, EventArgs e)
{
manager = new WorkflowRuntimeManager(new System.Workflow.Runtime.WorkflowRuntime());
AddService(manager.WorkflowRuntime);
manager.WorkflowRuntime.WorkflowIdled += new EventHandler<WorkflowEventArgs>(WorkflowRuntime_WorkflowIdled);
manager.WorkflowRuntime.StartRuntime();
}
private delegate void UpdateDelegate();
void WorkflowRuntime_WorkflowIdled(object sender, WorkflowEventArgs e)
{
UpdateDelegate theDelegate = delegate()
{
EnableEventButtons(false);
ReadOnlyCollection<WorkflowQueueInfo> queueInfoData = instanceWrapper.WorkflowInstance.GetWorkflowQueueData();
if (queueInfoData != null)
{
foreach (WorkflowQueueInfo info in queueInfoData)
{
EventQueueName eventQueue = info.QueueName as EventQueueName;
if (eventQueue == null)
{
break;
}
EnableButtonForEvent(eventQueue.MethodName);
}
}
StateMachineWorkflowInstance stateMachine = new StateMachineWorkflowInstance(manager.WorkflowRuntime, instanceWrapper.WorkflowInstance.InstanceId);
lblStateMessage.Text = stateMachine.CurrentStateName;
};
this.Invoke(theDelegate);
}
private void EnableEventButtons(bool flag)
{
btnStartEngine.Enabled = flag;
btnGoReverse.Enabled = flag;
btnGoForward.Enabled = flag;
btnStopEngine.Enabled = flag;
btnStopMovement.Enabled = flag;
btnLeaveCar.Enabled = flag;
btnBeepHorn.Enabled = flag;
}
private void EnableButtonForEvent(String eventName)
{
//如果控件的 Tag 属性和事件名称相同,就启用
foreach (Control control in this.Controls)
{
if (control is Button && control.Tag != null)
{
if (control.Tag.ToString() == eventName)
{
control.Enabled = true;
}
}
}
}
private void AddService(WorkflowRuntime instance)
{
ExternalDataExchangeService exchangeService = new ExternalDataExchangeService();
instance.AddService(exchangeService);
carService = new CarService();
exchangeService.AddService(carService);
}
private void btnNewCar_Click(object sender, EventArgs e)
{
instanceWrapper = manager.StartWorkflow(typeof(CarWorkflow), null);
}
private void btnStartEngine_Click(object sender, EventArgs e)
{
if(carService!=null)
{
carService.OnStartEngine(new ExternalDataEventArgs(instanceWrapper.Id));
}
}
private void btnStopEngine_Click(object sender, EventArgs e)
{
if (carService != null)
{
carService.OnStopEngine(new ExternalDataEventArgs(instanceWrapper.Id));
}
}
private void btnStopMovement_Click(object sender, EventArgs e)
{
if (carService != null)
{
carService.OnStopMovement(new ExternalDataEventArgs(instanceWrapper.Id));
}
}
private void btnGoForward_Click(object sender, EventArgs e)
{
if (carService != null)
{
carService.OnGoForward(new ExternalDataEventArgs(instanceWrapper.Id));
}
}
private void btnGoReverse_Click(object sender, EventArgs e)
{
if (carService != null)
{
carService.OnGoReverse(new ExternalDataEventArgs(instanceWrapper.Id));
}
}
private void btnLeaveCar_Click(object sender, EventArgs e)
{
if (carService != null)
{
carService.OnLeaveCar(new ExternalDataEventArgs(instanceWrapper.Id));
}
}
private void btnBeepHorn_Click(object sender, EventArgs e)
{
if (carService != null)
{
carService.OnBeepHorn(new ExternalDataEventArgs(instanceWrapper.Id));
}
}
}
初始图运行图
我们也可以实现多个工作流实例
public partial class ListCar1 : Form
{
private WorkflowRuntimeManager manager;
private CarService carService;
private Dictionary<Guid, StateMachineInstanceWrapper> instanceWrappers;
private StateMachineInstanceWrapper instance;
private delegate void UpdateDelegate();
public ListCar1()
{
InitializeComponent();
btnStartEngine.Tag = "StartEngine";
btnStopEngine.Tag = "StopEngine";
btnGoForward.Tag = "GoForward";
btnGoReverse.Tag = "GoReverse";
btnStopMovement.Tag = "StopMovement";
btnBeepHorn.Tag = "BeepHorn";
btnLeaveCar.Tag = "LeaveCar";
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
instanceWrappers = new Dictionary<Guid, StateMachineInstanceWrapper>();
manager = new WorkflowRuntimeManager(new WorkflowRuntime());
manager.WorkflowRuntime.WorkflowIdled += new EventHandler<WorkflowEventArgs>(WorkflowRuntime_WorkflowIdled);
AddService(manager.WorkflowRuntime);
manager.WorkflowRuntime.StartRuntime();
}
private void AddService(WorkflowRuntime workflowRuntime)
{
ExternalDataExchangeService dataexchangeService = new ExternalDataExchangeService();
workflowRuntime.AddService(dataexchangeService);
carService = new CarService();
dataexchangeService.AddService(carService);
}
void WorkflowRuntime_WorkflowIdled(object sender, WorkflowEventArgs e)
{
UpdateCanDo();
}
private void btnNewCar_Click(object sender, EventArgs e)
{
WorkflowInstanceWrapper instanceWrapper = manager.StartWorkflow(typeof(CarWorkflow),null);
instance = new StateMachineInstanceWrapper(manager.WorkflowRuntime, instanceWrapper.Id);
instanceWrappers.Add(instanceWrapper.Id,new StateMachineInstanceWrapper(manager.WorkflowRuntime, instanceWrapper.Id));
ListToBind();
UpdateList(instance.Id, "NewCar");
}
private void ListToBind()
{
if (instanceWrappers.Count > 0)
{
BindingSource source = new BindingSource();
dataGridView1.DataSource = source;
source.DataSource = instanceWrappers.Values;
dataGridView1.Columns[0].MinimumWidth = 220;
dataGridView1.Columns[1].MinimumWidth = 80;
dataGridView1.Columns[2].MinimumWidth = 30;
dataGridView1.Refresh();
}
}
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
UpdateCanDo();
}
private void UpdateCanDo()
{
if (this.dataGridView1.SelectedRows.Count > 0)
{
DataGridViewRow selectedRow = dataGridView1.SelectedRows[0];
StateMachineInstanceWrapper wrapper = selectedRow.DataBoundItem as StateMachineInstanceWrapper;
instance = new StateMachineInstanceWrapper(manager.WorkflowRuntime, wrapper.Id);
UpdateDelegate theDelegate = delegate()
{
EnableEventButtons(false);
ReadOnlyCollection<WorkflowQueueInfo> queueInfoData = instance.WorkflowInstance.GetWorkflowQueueData();
if (queueInfoData != null)
{
foreach (WorkflowQueueInfo info in queueInfoData)
{
EventQueueName eventQueue = info.QueueName as EventQueueName;
if (eventQueue == null)
{
break;
}
EnableButtonForEvent(eventQueue.MethodName);
}
}
};
this.Invoke(theDelegate);
}
}
private void EnableEventButtons(bool flag)
{
btnNewCar.Enabled = flag;
btnStartEngine.Enabled = flag;
btnGoReverse.Enabled = flag;
btnGoForward.Enabled = flag;
btnStopEngine.Enabled = flag;
btnStopMovement.Enabled = flag;
btnLeaveCar.Enabled = flag;
btnBeepHorn.Enabled = flag;
}
private void EnableButtonForEvent(String eventName)
{
foreach (Control control in this.Controls)
{
if (control is Button && control.Tag != null)
{
if (control.Tag.ToString() == eventName)
{
control.Enabled = true;
}
}
}
btnNewCar.Enabled = true;
}
private void btnStartEngine_Click(object sender, EventArgs e)
{
if (carService != null&&instance!=null)
{
carService.OnStartEngine(new ExternalDataEventArgs(instance.Id));
UpdateList(instance.Id, "startEngine");
}
}
private void UpdateList(Guid instanceId, string message)
{
if (instanceWrappers.ContainsKey(instanceId))
{
instanceWrappers.SingleOrDefault(c => c.Key == instanceId).Value.CurrentStatus = message;
}
}
private void btnStopEngine_Click(object sender, EventArgs e)
{
if (carService != null&&instance!=null)
{
carService.OnStopEngine(new ExternalDataEventArgs(instance.Id));
UpdateList(instance.Id, "StopEngine");
}
}
private void btnStopMovement_Click(object sender, EventArgs e)
{
if (carService != null && instance != null)
{
carService.OnStopMovement(new ExternalDataEventArgs(instance.Id));
UpdateList(instance.Id, "StopMovement");
}
}
private void btnGoForward_Click(object sender, EventArgs e)
{
if (carService != null && instance != null)
{
carService.OnGoForward(new ExternalDataEventArgs(instance.Id));
UpdateList(instance.Id, "GoForward");
}
}
private void btnGoReverse_Click(object sender, EventArgs e)
{
if (carService != null && instance != null)
{
carService.OnGoReverse(new ExternalDataEventArgs(instance.Id));
UpdateList(instance.Id, "GoReverse");
}
}
private void btnBeepHorn_Click(object sender, EventArgs e)
{
if (carService != null && instance != null)
{
carService.OnBeepHorn(new ExternalDataEventArgs(instance.Id));
UpdateList(instance.Id, "BeepHorn");
}
}
private void btnLeaveCar_Click(object sender, EventArgs e)
{
if (carService != null && instance != null)
{
carService.OnLeaveCar(new ExternalDataEventArgs(instance.Id));
UpdateList(instance.Id, "LeaveCar");
}
}
}
public class StateMachineInstanceWrapper
{
private StateMachineWorkflowInstance instance;
public StateMachineInstanceWrapper(WorkflowRuntime runtime,Guid instanceId)
{
instance = new StateMachineWorkflowInstance(runtime, instanceId);
}
public Guid Id
{
get
{
return instance.InstanceId;
}
}
public string Status
{
get
{
return instance.CurrentStateName;
}
}
public string CurrentStatus
{
get;
set;
}
public WorkflowInstance WorkflowInstance
{
get
{
return instance.WorkflowInstance;
}
}
}