Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Activities / State.cs / 1305376 / State.cs
namespace System.Workflow.Activities { #region Imports using System; using System.Text; using System.Reflection; using System.Collections; using System.CodeDom; using System.ComponentModel; using System.ComponentModel.Design; using System.Drawing.Design; using System.Drawing; using System.Diagnostics; using System.Workflow.ComponentModel; using System.Workflow.ComponentModel.Design; using System.Workflow.Runtime; using System.Runtime.Serialization; using System.Collections.Generic; using System.ComponentModel.Design.Serialization; using System.Xml.Serialization; using System.Workflow.ComponentModel.Compiler; #endregion [SRDescription(SR.StateActivityDescription)] [ToolboxItem(typeof(ActivityToolboxItem))] [Designer(typeof(StateDesigner), typeof(IDesigner))] [ToolboxBitmap(typeof(StateActivity), "Resources.StateActivity.png")] [ActivityValidator(typeof(StateActivityValidator))] [SRCategory(SR.Standard)] [System.Runtime.InteropServices.ComVisible(false)] public class StateActivity : CompositeActivity { #region Fields public const string StateChangeTrackingDataKey = "StateActivity.StateChange"; internal static DependencyProperty StateMachineExecutionStateProperty = DependencyProperty.Register(StateMachineExecutionState.StateMachineExecutionStateKey, typeof(StateMachineExecutionState), typeof(StateActivity), new PropertyMetadata()); #endregion Fields #region Constructor public StateActivity() { } public StateActivity(string name) : base(name) { } #endregion Constructor #region Methods protected override void OnClosed(IServiceProvider provider) { base.RemoveProperty(StateActivity.StateMachineExecutionStateProperty); } #region Public Methods [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] private Activity GetDynamicActivity(Activity childActivity) { if (childActivity == null) throw new ArgumentNullException("childActivity"); if (!this.EnabledActivities.Contains(childActivity)) throw new ArgumentException(SR.GetString(SR.Error_StateChildNotFound), "childActivity"); else { Activity[] dynamicChildActivity = this.GetDynamicActivities(childActivity); if (dynamicChildActivity.Length != 0) return dynamicChildActivity[0]; else return null; } } public Activity GetDynamicActivity(String childActivityName) { if (childActivityName == null) throw new ArgumentNullException("childActivityName"); Activity childActivity = null; for (int i = 0; i < this.EnabledActivities.Count; ++i) { if (this.EnabledActivities[i].QualifiedName.Equals(childActivityName)) { childActivity = this.EnabledActivities[i]; break; } } if (childActivity != null) return GetDynamicActivity(childActivity); throw new ArgumentException(SR.GetString(SR.Error_StateChildNotFound), "childActivityName"); } #endregion Public Methods protected override void Initialize(IServiceProvider provider) { base.Initialize(provider); ActivityExecutionContext context = (ActivityExecutionContext)provider; StateActivity rootState = StateMachineHelpers.GetRootState(this); if (!StateMachineHelpers.IsStateMachine(rootState)) throw new InvalidOperationException(SR.GetError_StateActivityMustBeContainedInAStateMachine()); string initialStateName = StateMachineHelpers.GetInitialStateName(this); if (String.IsNullOrEmpty(initialStateName)) throw new InvalidOperationException(SR.GetError_CannotExecuteStateMachineWithoutInitialState()); // if (this.QualifiedName != initialStateName) StateMachineSubscriptionManager.DisableStateWorkflowQueues(context, this); } protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext) { if (executionContext == null) throw new ArgumentNullException("executionContext"); if (StateMachineHelpers.IsRootState(this)) { ExecuteRootState(executionContext); } else { if (StateMachineHelpers.IsLeafState(this)) { ExecuteLeafState(executionContext); } else { ExecuteState(executionContext); } } return this.ExecutionStatus; } private void ExecuteRootState(ActivityExecutionContext context) { StateActivity state = (StateActivity)context.Activity; StateMachineExecutionState executionState = new StateMachineExecutionState(this.WorkflowInstanceId); executionState.SchedulerBusy = false; state.SetValue(StateActivity.StateMachineExecutionStateProperty, executionState); executionState.SubscriptionManager.CreateSetStateEventQueue(context); string initialStateName = StateMachineHelpers.GetInitialStateName(state); executionState.CalculateStateTransition(this, initialStateName); executionState.ProcessActions(context); } private static void ExecuteState(ActivityExecutionContext context) { StateMachineExecutionState executionState = GetExecutionState(context); executionState.SchedulerBusy = false; executionState.ProcessActions(context); } private static void ExecuteLeafState(ActivityExecutionContext context) { StateActivity state = (StateActivity)context.Activity; StateMachineExecutionState executionState = GetExecutionState(state); executionState.SchedulerBusy = false; executionState.CurrentStateName = state.QualifiedName; StateInitializationActivity stateInitialization = GetStateInitialization(context); if (stateInitialization != null) { ExecuteStateInitialization(context, stateInitialization); } else { EnteringLeafState(context); } } private static void EnteringLeafState(ActivityExecutionContext context) { if (context == null) throw new ArgumentNullException("context"); StateActivity state = (StateActivity)context.Activity; Debug.Assert(StateMachineHelpers.IsLeafState(state)); StateMachineExecutionState executionState = GetExecutionState(state); executionState.SubscriptionManager.SubscribeToSetStateEvent(context); string completedStateName = StateMachineHelpers.GetCompletedStateName(state); if (StateMachineHelpers.IsCompletedState(state)) { // make sure that we track that we entered the completed state EnteringStateAction enteringState = new EnteringStateAction(state.QualifiedName); executionState.EnqueueAction(enteringState); executionState.ProcessActions(context); // this is the final state, so we start completing this tree executionState.Completed = true; LeavingState(context); } else { if (String.IsNullOrEmpty(executionState.NextStateName)) { executionState.SubscriptionManager.ReevaluateSubscriptions(context); EnteringStateAction enteringState = new EnteringStateAction(state.QualifiedName); executionState.EnqueueAction(enteringState); executionState.LockQueue(); } else { // The StateInitialization requested a state transtion EnteringStateAction enteringState = new EnteringStateAction(state.QualifiedName); executionState.EnqueueAction(enteringState); executionState.ProcessTransitionRequest(context); } executionState.ProcessActions(context); } } internal static void LeavingState(ActivityExecutionContext context) { if (context == null) throw new ArgumentNullException("context"); StateActivity state = (StateActivity)context.Activity; if (StateMachineHelpers.IsLeafState(state)) { StateFinalizationActivity stateFinalization = GetStateFinalization(context); if (stateFinalization == null) Complete(context); else ExecuteStateFinalization(context, stateFinalization); } else Complete(context); } private static void CleanUp(ActivityExecutionContext context) { if (context == null) throw new ArgumentNullException("context"); StateActivity state = (StateActivity)context.Activity; if (state.ExecutionStatus == ActivityExecutionStatus.Faulting) return; // if we're faulting, then we're already in a bad state, so we don't try to unsubscribe StateMachineExecutionState executionState = GetExecutionState(state); StateMachineSubscriptionManager subscriptionManager = executionState.SubscriptionManager; subscriptionManager.UnsubscribeState(context); if (StateMachineHelpers.IsRootState(state)) subscriptionManager.DeleteSetStateEventQueue(context); else if (StateMachineHelpers.IsLeafState(state)) subscriptionManager.UnsubscribeToSetStateEvent(context); } protected override ActivityExecutionStatus Cancel(ActivityExecutionContext executionContext) { if (executionContext == null) throw new ArgumentNullException("executionContext"); CleanUp(executionContext); Debug.Assert(executionContext.Activity == this); bool canCloseNow = true; ActivityExecutionContextManager contextManager = executionContext.ExecutionContextManager; foreach (ActivityExecutionContext existingContext in contextManager.ExecutionContexts) { if (existingContext.Activity.Parent == this) { canCloseNow = false; if (existingContext.Activity.ExecutionStatus == ActivityExecutionStatus.Executing) existingContext.CancelActivity(existingContext.Activity); } } return canCloseNow ? ActivityExecutionStatus.Closed : this.ExecutionStatus; } private static void Complete(ActivityExecutionContext context) { if (context == null) throw new ArgumentNullException("context"); StateActivity state = (StateActivity)context.Activity; StateMachineExecutionState executionState = GetExecutionState(state); if (StateMachineHelpers.IsLeafState(state)) { executionState.PreviousStateName = state.Name; } CleanUp(context); executionState.SchedulerBusy = true; context.CloseActivity(); } private static void ExecuteChild(ActivityExecutionContext context, Activity childActivity) { if (context == null) throw new ArgumentNullException("context"); if (childActivity == null) throw new ArgumentNullException("childActivity"); StateActivity state = (StateActivity)context.Activity; StateMachineExecutionState executionState = GetExecutionState(state); Debug.Assert(!executionState.SchedulerBusy); executionState.SchedulerBusy = true; ActivityExecutionContextManager contextManager = context.ExecutionContextManager; ActivityExecutionContext childContext = contextManager.CreateExecutionContext(childActivity); childContext.Activity.Closed += state.HandleChildActivityClosed; childContext.ExecuteActivity(childContext.Activity); } private static void CleanupChildAtClosure(ActivityExecutionContext context, Activity childActivity) { if (context == null) throw new ArgumentNullException("context"); if (childActivity == null) throw new ArgumentNullException("childActivity"); StateActivity state = (StateActivity)context.Activity; StateMachineExecutionState executionState = GetExecutionState(state); childActivity.Closed -= state.HandleChildActivityClosed; ActivityExecutionContextManager contextManager = context.ExecutionContextManager; ActivityExecutionContext childContext = contextManager.GetExecutionContext(childActivity); contextManager.CompleteExecutionContext(childContext); } internal void RaiseProcessActionEvent(ActivityExecutionContext context) { StateMachineExecutionState executionState = GetExecutionState(context); Debug.Assert(!executionState.SchedulerBusy); executionState.SchedulerBusy = true; base.Invoke(this.HandleProcessActionEvent, new EventArgs()); } private void HandleProcessActionEvent(object sender, EventArgs eventArgs) { ActivityExecutionContext context = sender as ActivityExecutionContext; if (context == null) throw new ArgumentException(SR.Error_SenderMustBeActivityExecutionContext, "sender"); StateMachineExecutionState executionState = GetExecutionState(context); executionState.SchedulerBusy = false; executionState.ProcessActions(context); } #region HandleStatusChange private void HandleChildActivityClosed(object sender, ActivityExecutionStatusChangedEventArgs eventArgs) { ActivityExecutionContext context = sender as ActivityExecutionContext; if (context == null) throw new ArgumentException(SR.Error_SenderMustBeActivityExecutionContext, "sender"); if (eventArgs == null) throw new ArgumentNullException("eventArgs"); Activity completedChildActivity = eventArgs.Activity; StateActivity state = (StateActivity)context.Activity; StateMachineExecutionState executionState = GetExecutionState(context); executionState.SchedulerBusy = false; CleanupChildAtClosure(context, completedChildActivity); switch (state.ExecutionStatus) { case ActivityExecutionStatus.Canceling: case ActivityExecutionStatus.Faulting: context.CloseActivity(); return; case ActivityExecutionStatus.Executing: if (completedChildActivity is EventDrivenActivity) { HandleEventDrivenCompleted(context); return; } StateInitializationActivity stateInitialization = completedChildActivity as StateInitializationActivity; if (stateInitialization != null) { HandleStateInitializationCompleted(context, stateInitialization); return; } if (completedChildActivity is StateFinalizationActivity) { HandleStateFinalizationCompleted(context); return; } if (completedChildActivity is StateActivity) { HandleSubStateCompleted(context); return; } InvalidChildActivity(state); break; default: throw new InvalidOperationException(SR.GetInvalidActivityStatus(context.Activity)); } } private static void InvalidChildActivity(StateActivity state) { if (StateMachineHelpers.IsLeafState(state)) throw new InvalidOperationException(SR.GetError_InvalidLeafStateChild()); else throw new InvalidOperationException(SR.GetError_InvalidCompositeStateChild()); } internal static void ExecuteEventDriven(ActivityExecutionContext context, EventDrivenActivity eventDriven) { StateMachineExecutionState executionState = GetExecutionState(context); Debug.Assert(!executionState.HasEnqueuedActions); ExecuteChild(context, eventDriven); } private static void HandleEventDrivenCompleted(ActivityExecutionContext context) { if (context == null) throw new ArgumentNullException("context"); StateActivity state = (StateActivity)context.Activity; StateMachineExecutionState executionState = GetExecutionState(context); if (String.IsNullOrEmpty(executionState.NextStateName)) { executionState.SubscriptionManager.ReevaluateSubscriptions(context); executionState.LockQueue(); } else executionState.ProcessTransitionRequest(context); executionState.ProcessActions(context); } private static void ExecuteStateInitialization(ActivityExecutionContext context, StateInitializationActivity stateInitialization) { StateMachineExecutionState executionState = GetExecutionState(context); Debug.Assert(!executionState.HasEnqueuedActions); ExecuteChild(context, stateInitialization); } private static void HandleStateInitializationCompleted(ActivityExecutionContext context, StateInitializationActivity stateInitialization) { if (context == null) throw new ArgumentNullException("context"); if (stateInitialization == null) throw new ArgumentNullException("stateInitialization"); StateActivity state = (StateActivity)context.Activity; StateMachineExecutionState executionState = GetExecutionState(state); if (!String.IsNullOrEmpty(executionState.NextStateName) && executionState.NextStateName.Equals(state.QualifiedName)) throw new InvalidOperationException(SR.GetInvalidSetStateInStateInitialization()); EnteringLeafState(context); } private static void ExecuteStateFinalization(ActivityExecutionContext context, StateFinalizationActivity stateFinalization) { StateMachineExecutionState executionState = GetExecutionState(context); ExecuteChild(context, stateFinalization); } private static void HandleStateFinalizationCompleted(ActivityExecutionContext context) { if (context == null) throw new ArgumentNullException("context"); StateMachineExecutionState executionState = GetExecutionState(context); Complete(context); } internal static void ExecuteState(ActivityExecutionContext context, StateActivity state) { StateMachineExecutionState executionState = GetExecutionState(context); ExecuteChild(context, state); } private static void HandleSubStateCompleted(ActivityExecutionContext context) { if (context == null) throw new ArgumentNullException("context"); StateMachineExecutionState executionState = GetExecutionState(context); if (executionState.Completed) { // We're closing the state machine LeavingState(context); } else { executionState.ProcessActions(context); } } #endregion #region Helper methods private static StateInitializationActivity GetStateInitialization(ActivityExecutionContext context) { StateActivity state = (StateActivity)context.Activity; Debug.Assert(StateMachineHelpers.IsLeafState(state), "GetStateInitialization: StateInitialization is only allowed in a leaf node state"); return GetHandlerActivity (context); } private static StateFinalizationActivity GetStateFinalization(ActivityExecutionContext context) { StateActivity state = (StateActivity)context.Activity; Debug.Assert(StateMachineHelpers.IsLeafState(state), "GetStateFinalization: StateFinalization is only allowed in a leaf node state"); return GetHandlerActivity (context); } private static T GetHandlerActivity (ActivityExecutionContext context) where T : class { StateActivity state = (StateActivity)context.Activity; foreach (Activity activity in state.EnabledActivities) { T handler = activity as T; if (handler != null) { return handler; } } return null; } private static StateMachineExecutionState GetExecutionState(ActivityExecutionContext context) { if (context == null) throw new ArgumentNullException("context"); StateActivity state = (StateActivity)context.Activity; StateMachineExecutionState executionState = GetExecutionState(state); return executionState; } private static StateMachineExecutionState GetExecutionState(StateActivity state) { if (state == null) throw new ArgumentNullException("state"); StateActivity rootState = StateMachineHelpers.GetRootState(state); StateMachineExecutionState executionState = StateMachineExecutionState.Get(rootState); return executionState; } #endregion #endregion Methods #region Dynamic Update Functions protected override void OnActivityChangeAdd(ActivityExecutionContext executionContext, Activity addedActivity) { if (executionContext == null) throw new ArgumentNullException("executionContext"); if (addedActivity == null) throw new ArgumentNullException("addedActivity"); if (!addedActivity.Enabled) return; if (executionContext.Activity.ExecutionStatus != ActivityExecutionStatus.Executing) return; // activity is not executing EventDrivenActivity eventDriven = addedActivity as EventDrivenActivity; if (eventDriven == null) return; // Activity we added is an EventDrivenActivity // First we disable the queue StateMachineSubscriptionManager.ChangeEventDrivenQueueState(executionContext, eventDriven, false); StateActivity rootState = StateMachineHelpers.GetRootState(executionContext.Activity as StateActivity); StateMachineExecutionState executionState = StateMachineExecutionState.Get(rootState); StateActivity currentState = StateMachineHelpers.GetCurrentState(executionContext); if (currentState == null) return; // Dynamic update happened before we entered the initial state StateMachineSubscriptionManager subscriptionManager = executionState.SubscriptionManager; subscriptionManager.ReevaluateSubscriptions(executionContext); executionState.LockQueue(); executionState.ProcessActions(executionContext); } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. namespace System.Workflow.Activities { #region Imports using System; using System.Text; using System.Reflection; using System.Collections; using System.CodeDom; using System.ComponentModel; using System.ComponentModel.Design; using System.Drawing.Design; using System.Drawing; using System.Diagnostics; using System.Workflow.ComponentModel; using System.Workflow.ComponentModel.Design; using System.Workflow.Runtime; using System.Runtime.Serialization; using System.Collections.Generic; using System.ComponentModel.Design.Serialization; using System.Xml.Serialization; using System.Workflow.ComponentModel.Compiler; #endregion [SRDescription(SR.StateActivityDescription)] [ToolboxItem(typeof(ActivityToolboxItem))] [Designer(typeof(StateDesigner), typeof(IDesigner))] [ToolboxBitmap(typeof(StateActivity), "Resources.StateActivity.png")] [ActivityValidator(typeof(StateActivityValidator))] [SRCategory(SR.Standard)] [System.Runtime.InteropServices.ComVisible(false)] public class StateActivity : CompositeActivity { #region Fields public const string StateChangeTrackingDataKey = "StateActivity.StateChange"; internal static DependencyProperty StateMachineExecutionStateProperty = DependencyProperty.Register(StateMachineExecutionState.StateMachineExecutionStateKey, typeof(StateMachineExecutionState), typeof(StateActivity), new PropertyMetadata()); #endregion Fields #region Constructor public StateActivity() { } public StateActivity(string name) : base(name) { } #endregion Constructor #region Methods protected override void OnClosed(IServiceProvider provider) { base.RemoveProperty(StateActivity.StateMachineExecutionStateProperty); } #region Public Methods [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] private Activity GetDynamicActivity(Activity childActivity) { if (childActivity == null) throw new ArgumentNullException("childActivity"); if (!this.EnabledActivities.Contains(childActivity)) throw new ArgumentException(SR.GetString(SR.Error_StateChildNotFound), "childActivity"); else { Activity[] dynamicChildActivity = this.GetDynamicActivities(childActivity); if (dynamicChildActivity.Length != 0) return dynamicChildActivity[0]; else return null; } } public Activity GetDynamicActivity(String childActivityName) { if (childActivityName == null) throw new ArgumentNullException("childActivityName"); Activity childActivity = null; for (int i = 0; i < this.EnabledActivities.Count; ++i) { if (this.EnabledActivities[i].QualifiedName.Equals(childActivityName)) { childActivity = this.EnabledActivities[i]; break; } } if (childActivity != null) return GetDynamicActivity(childActivity); throw new ArgumentException(SR.GetString(SR.Error_StateChildNotFound), "childActivityName"); } #endregion Public Methods protected override void Initialize(IServiceProvider provider) { base.Initialize(provider); ActivityExecutionContext context = (ActivityExecutionContext)provider; StateActivity rootState = StateMachineHelpers.GetRootState(this); if (!StateMachineHelpers.IsStateMachine(rootState)) throw new InvalidOperationException(SR.GetError_StateActivityMustBeContainedInAStateMachine()); string initialStateName = StateMachineHelpers.GetInitialStateName(this); if (String.IsNullOrEmpty(initialStateName)) throw new InvalidOperationException(SR.GetError_CannotExecuteStateMachineWithoutInitialState()); // if (this.QualifiedName != initialStateName) StateMachineSubscriptionManager.DisableStateWorkflowQueues(context, this); } protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext) { if (executionContext == null) throw new ArgumentNullException("executionContext"); if (StateMachineHelpers.IsRootState(this)) { ExecuteRootState(executionContext); } else { if (StateMachineHelpers.IsLeafState(this)) { ExecuteLeafState(executionContext); } else { ExecuteState(executionContext); } } return this.ExecutionStatus; } private void ExecuteRootState(ActivityExecutionContext context) { StateActivity state = (StateActivity)context.Activity; StateMachineExecutionState executionState = new StateMachineExecutionState(this.WorkflowInstanceId); executionState.SchedulerBusy = false; state.SetValue(StateActivity.StateMachineExecutionStateProperty, executionState); executionState.SubscriptionManager.CreateSetStateEventQueue(context); string initialStateName = StateMachineHelpers.GetInitialStateName(state); executionState.CalculateStateTransition(this, initialStateName); executionState.ProcessActions(context); } private static void ExecuteState(ActivityExecutionContext context) { StateMachineExecutionState executionState = GetExecutionState(context); executionState.SchedulerBusy = false; executionState.ProcessActions(context); } private static void ExecuteLeafState(ActivityExecutionContext context) { StateActivity state = (StateActivity)context.Activity; StateMachineExecutionState executionState = GetExecutionState(state); executionState.SchedulerBusy = false; executionState.CurrentStateName = state.QualifiedName; StateInitializationActivity stateInitialization = GetStateInitialization(context); if (stateInitialization != null) { ExecuteStateInitialization(context, stateInitialization); } else { EnteringLeafState(context); } } private static void EnteringLeafState(ActivityExecutionContext context) { if (context == null) throw new ArgumentNullException("context"); StateActivity state = (StateActivity)context.Activity; Debug.Assert(StateMachineHelpers.IsLeafState(state)); StateMachineExecutionState executionState = GetExecutionState(state); executionState.SubscriptionManager.SubscribeToSetStateEvent(context); string completedStateName = StateMachineHelpers.GetCompletedStateName(state); if (StateMachineHelpers.IsCompletedState(state)) { // make sure that we track that we entered the completed state EnteringStateAction enteringState = new EnteringStateAction(state.QualifiedName); executionState.EnqueueAction(enteringState); executionState.ProcessActions(context); // this is the final state, so we start completing this tree executionState.Completed = true; LeavingState(context); } else { if (String.IsNullOrEmpty(executionState.NextStateName)) { executionState.SubscriptionManager.ReevaluateSubscriptions(context); EnteringStateAction enteringState = new EnteringStateAction(state.QualifiedName); executionState.EnqueueAction(enteringState); executionState.LockQueue(); } else { // The StateInitialization requested a state transtion EnteringStateAction enteringState = new EnteringStateAction(state.QualifiedName); executionState.EnqueueAction(enteringState); executionState.ProcessTransitionRequest(context); } executionState.ProcessActions(context); } } internal static void LeavingState(ActivityExecutionContext context) { if (context == null) throw new ArgumentNullException("context"); StateActivity state = (StateActivity)context.Activity; if (StateMachineHelpers.IsLeafState(state)) { StateFinalizationActivity stateFinalization = GetStateFinalization(context); if (stateFinalization == null) Complete(context); else ExecuteStateFinalization(context, stateFinalization); } else Complete(context); } private static void CleanUp(ActivityExecutionContext context) { if (context == null) throw new ArgumentNullException("context"); StateActivity state = (StateActivity)context.Activity; if (state.ExecutionStatus == ActivityExecutionStatus.Faulting) return; // if we're faulting, then we're already in a bad state, so we don't try to unsubscribe StateMachineExecutionState executionState = GetExecutionState(state); StateMachineSubscriptionManager subscriptionManager = executionState.SubscriptionManager; subscriptionManager.UnsubscribeState(context); if (StateMachineHelpers.IsRootState(state)) subscriptionManager.DeleteSetStateEventQueue(context); else if (StateMachineHelpers.IsLeafState(state)) subscriptionManager.UnsubscribeToSetStateEvent(context); } protected override ActivityExecutionStatus Cancel(ActivityExecutionContext executionContext) { if (executionContext == null) throw new ArgumentNullException("executionContext"); CleanUp(executionContext); Debug.Assert(executionContext.Activity == this); bool canCloseNow = true; ActivityExecutionContextManager contextManager = executionContext.ExecutionContextManager; foreach (ActivityExecutionContext existingContext in contextManager.ExecutionContexts) { if (existingContext.Activity.Parent == this) { canCloseNow = false; if (existingContext.Activity.ExecutionStatus == ActivityExecutionStatus.Executing) existingContext.CancelActivity(existingContext.Activity); } } return canCloseNow ? ActivityExecutionStatus.Closed : this.ExecutionStatus; } private static void Complete(ActivityExecutionContext context) { if (context == null) throw new ArgumentNullException("context"); StateActivity state = (StateActivity)context.Activity; StateMachineExecutionState executionState = GetExecutionState(state); if (StateMachineHelpers.IsLeafState(state)) { executionState.PreviousStateName = state.Name; } CleanUp(context); executionState.SchedulerBusy = true; context.CloseActivity(); } private static void ExecuteChild(ActivityExecutionContext context, Activity childActivity) { if (context == null) throw new ArgumentNullException("context"); if (childActivity == null) throw new ArgumentNullException("childActivity"); StateActivity state = (StateActivity)context.Activity; StateMachineExecutionState executionState = GetExecutionState(state); Debug.Assert(!executionState.SchedulerBusy); executionState.SchedulerBusy = true; ActivityExecutionContextManager contextManager = context.ExecutionContextManager; ActivityExecutionContext childContext = contextManager.CreateExecutionContext(childActivity); childContext.Activity.Closed += state.HandleChildActivityClosed; childContext.ExecuteActivity(childContext.Activity); } private static void CleanupChildAtClosure(ActivityExecutionContext context, Activity childActivity) { if (context == null) throw new ArgumentNullException("context"); if (childActivity == null) throw new ArgumentNullException("childActivity"); StateActivity state = (StateActivity)context.Activity; StateMachineExecutionState executionState = GetExecutionState(state); childActivity.Closed -= state.HandleChildActivityClosed; ActivityExecutionContextManager contextManager = context.ExecutionContextManager; ActivityExecutionContext childContext = contextManager.GetExecutionContext(childActivity); contextManager.CompleteExecutionContext(childContext); } internal void RaiseProcessActionEvent(ActivityExecutionContext context) { StateMachineExecutionState executionState = GetExecutionState(context); Debug.Assert(!executionState.SchedulerBusy); executionState.SchedulerBusy = true; base.Invoke (this.HandleProcessActionEvent, new EventArgs()); } private void HandleProcessActionEvent(object sender, EventArgs eventArgs) { ActivityExecutionContext context = sender as ActivityExecutionContext; if (context == null) throw new ArgumentException(SR.Error_SenderMustBeActivityExecutionContext, "sender"); StateMachineExecutionState executionState = GetExecutionState(context); executionState.SchedulerBusy = false; executionState.ProcessActions(context); } #region HandleStatusChange private void HandleChildActivityClosed(object sender, ActivityExecutionStatusChangedEventArgs eventArgs) { ActivityExecutionContext context = sender as ActivityExecutionContext; if (context == null) throw new ArgumentException(SR.Error_SenderMustBeActivityExecutionContext, "sender"); if (eventArgs == null) throw new ArgumentNullException("eventArgs"); Activity completedChildActivity = eventArgs.Activity; StateActivity state = (StateActivity)context.Activity; StateMachineExecutionState executionState = GetExecutionState(context); executionState.SchedulerBusy = false; CleanupChildAtClosure(context, completedChildActivity); switch (state.ExecutionStatus) { case ActivityExecutionStatus.Canceling: case ActivityExecutionStatus.Faulting: context.CloseActivity(); return; case ActivityExecutionStatus.Executing: if (completedChildActivity is EventDrivenActivity) { HandleEventDrivenCompleted(context); return; } StateInitializationActivity stateInitialization = completedChildActivity as StateInitializationActivity; if (stateInitialization != null) { HandleStateInitializationCompleted(context, stateInitialization); return; } if (completedChildActivity is StateFinalizationActivity) { HandleStateFinalizationCompleted(context); return; } if (completedChildActivity is StateActivity) { HandleSubStateCompleted(context); return; } InvalidChildActivity(state); break; default: throw new InvalidOperationException(SR.GetInvalidActivityStatus(context.Activity)); } } private static void InvalidChildActivity(StateActivity state) { if (StateMachineHelpers.IsLeafState(state)) throw new InvalidOperationException(SR.GetError_InvalidLeafStateChild()); else throw new InvalidOperationException(SR.GetError_InvalidCompositeStateChild()); } internal static void ExecuteEventDriven(ActivityExecutionContext context, EventDrivenActivity eventDriven) { StateMachineExecutionState executionState = GetExecutionState(context); Debug.Assert(!executionState.HasEnqueuedActions); ExecuteChild(context, eventDriven); } private static void HandleEventDrivenCompleted(ActivityExecutionContext context) { if (context == null) throw new ArgumentNullException("context"); StateActivity state = (StateActivity)context.Activity; StateMachineExecutionState executionState = GetExecutionState(context); if (String.IsNullOrEmpty(executionState.NextStateName)) { executionState.SubscriptionManager.ReevaluateSubscriptions(context); executionState.LockQueue(); } else executionState.ProcessTransitionRequest(context); executionState.ProcessActions(context); } private static void ExecuteStateInitialization(ActivityExecutionContext context, StateInitializationActivity stateInitialization) { StateMachineExecutionState executionState = GetExecutionState(context); Debug.Assert(!executionState.HasEnqueuedActions); ExecuteChild(context, stateInitialization); } private static void HandleStateInitializationCompleted(ActivityExecutionContext context, StateInitializationActivity stateInitialization) { if (context == null) throw new ArgumentNullException("context"); if (stateInitialization == null) throw new ArgumentNullException("stateInitialization"); StateActivity state = (StateActivity)context.Activity; StateMachineExecutionState executionState = GetExecutionState(state); if (!String.IsNullOrEmpty(executionState.NextStateName) && executionState.NextStateName.Equals(state.QualifiedName)) throw new InvalidOperationException(SR.GetInvalidSetStateInStateInitialization()); EnteringLeafState(context); } private static void ExecuteStateFinalization(ActivityExecutionContext context, StateFinalizationActivity stateFinalization) { StateMachineExecutionState executionState = GetExecutionState(context); ExecuteChild(context, stateFinalization); } private static void HandleStateFinalizationCompleted(ActivityExecutionContext context) { if (context == null) throw new ArgumentNullException("context"); StateMachineExecutionState executionState = GetExecutionState(context); Complete(context); } internal static void ExecuteState(ActivityExecutionContext context, StateActivity state) { StateMachineExecutionState executionState = GetExecutionState(context); ExecuteChild(context, state); } private static void HandleSubStateCompleted(ActivityExecutionContext context) { if (context == null) throw new ArgumentNullException("context"); StateMachineExecutionState executionState = GetExecutionState(context); if (executionState.Completed) { // We're closing the state machine LeavingState(context); } else { executionState.ProcessActions(context); } } #endregion #region Helper methods private static StateInitializationActivity GetStateInitialization(ActivityExecutionContext context) { StateActivity state = (StateActivity)context.Activity; Debug.Assert(StateMachineHelpers.IsLeafState(state), "GetStateInitialization: StateInitialization is only allowed in a leaf node state"); return GetHandlerActivity (context); } private static StateFinalizationActivity GetStateFinalization(ActivityExecutionContext context) { StateActivity state = (StateActivity)context.Activity; Debug.Assert(StateMachineHelpers.IsLeafState(state), "GetStateFinalization: StateFinalization is only allowed in a leaf node state"); return GetHandlerActivity (context); } private static T GetHandlerActivity (ActivityExecutionContext context) where T : class { StateActivity state = (StateActivity)context.Activity; foreach (Activity activity in state.EnabledActivities) { T handler = activity as T; if (handler != null) { return handler; } } return null; } private static StateMachineExecutionState GetExecutionState(ActivityExecutionContext context) { if (context == null) throw new ArgumentNullException("context"); StateActivity state = (StateActivity)context.Activity; StateMachineExecutionState executionState = GetExecutionState(state); return executionState; } private static StateMachineExecutionState GetExecutionState(StateActivity state) { if (state == null) throw new ArgumentNullException("state"); StateActivity rootState = StateMachineHelpers.GetRootState(state); StateMachineExecutionState executionState = StateMachineExecutionState.Get(rootState); return executionState; } #endregion #endregion Methods #region Dynamic Update Functions protected override void OnActivityChangeAdd(ActivityExecutionContext executionContext, Activity addedActivity) { if (executionContext == null) throw new ArgumentNullException("executionContext"); if (addedActivity == null) throw new ArgumentNullException("addedActivity"); if (!addedActivity.Enabled) return; if (executionContext.Activity.ExecutionStatus != ActivityExecutionStatus.Executing) return; // activity is not executing EventDrivenActivity eventDriven = addedActivity as EventDrivenActivity; if (eventDriven == null) return; // Activity we added is an EventDrivenActivity // First we disable the queue StateMachineSubscriptionManager.ChangeEventDrivenQueueState(executionContext, eventDriven, false); StateActivity rootState = StateMachineHelpers.GetRootState(executionContext.Activity as StateActivity); StateMachineExecutionState executionState = StateMachineExecutionState.Get(rootState); StateActivity currentState = StateMachineHelpers.GetCurrentState(executionContext); if (currentState == null) return; // Dynamic update happened before we entered the initial state StateMachineSubscriptionManager subscriptionManager = executionState.SubscriptionManager; subscriptionManager.ReevaluateSubscriptions(executionContext); executionState.LockQueue(); executionState.ProcessActions(executionContext); } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SolidColorBrush.cs
- WebEventCodes.cs
- EraserBehavior.cs
- ListViewTableRow.cs
- RequestCacheValidator.cs
- HybridCollection.cs
- Dispatcher.cs
- HitTestDrawingContextWalker.cs
- AssociationSetEnd.cs
- ContractSearchPattern.cs
- ErrorReporting.cs
- UpdatePanelControlTrigger.cs
- ClassHandlersStore.cs
- Msmq3PoisonHandler.cs
- LookupBindingPropertiesAttribute.cs
- DrawingAttributes.cs
- PageAsyncTask.cs
- TextFormatterContext.cs
- Path.cs
- DelayedRegex.cs
- Token.cs
- Pen.cs
- PartitionerQueryOperator.cs
- ComponentResourceKeyConverter.cs
- WebExceptionStatus.cs
- SoapObjectInfo.cs
- TextContainer.cs
- FixedSOMFixedBlock.cs
- BamlLocalizableResource.cs
- Object.cs
- GorillaCodec.cs
- WindowsAuthenticationEventArgs.cs
- DataSourceGeneratorException.cs
- StringComparer.cs
- BitmapEffectInput.cs
- TextPattern.cs
- IArgumentProvider.cs
- DataBinder.cs
- WsatTransactionHeader.cs
- RemotingConfigParser.cs
- EntityClientCacheEntry.cs
- PropertyNames.cs
- FastPropertyAccessor.cs
- Win32.cs
- CodeArrayIndexerExpression.cs
- xsdvalidator.cs
- ScrollBarAutomationPeer.cs
- CodeNamespaceImportCollection.cs
- MexServiceChannelBuilder.cs
- IndexOutOfRangeException.cs
- HtmlValidatorAdapter.cs
- HMACRIPEMD160.cs
- PrintEvent.cs
- StreamGeometry.cs
- ValidatorUtils.cs
- documentsequencetextview.cs
- StyleBamlRecordReader.cs
- CatalogPart.cs
- DiffuseMaterial.cs
- MessageUtil.cs
- ControlCachePolicy.cs
- DependencyPropertyKey.cs
- ProxyManager.cs
- FormParameter.cs
- PartialArray.cs
- OutgoingWebResponseContext.cs
- WebEventTraceProvider.cs
- InstanceLockException.cs
- AppliedDeviceFiltersDialog.cs
- StateChangeEvent.cs
- coordinatorscratchpad.cs
- WebPartVerbsEventArgs.cs
- EdmFunction.cs
- Parameter.cs
- FreezableOperations.cs
- DesigntimeLicenseContext.cs
- WpfSharedXamlSchemaContext.cs
- RSAPKCS1SignatureDeformatter.cs
- CLRBindingWorker.cs
- SafeMILHandle.cs
- RsaEndpointIdentity.cs
- PerformanceCounterPermissionAttribute.cs
- PathSegment.cs
- DisableDpiAwarenessAttribute.cs
- HwndAppCommandInputProvider.cs
- DBPropSet.cs
- DataColumnMappingCollection.cs
- GACIdentityPermission.cs
- ServiceNameCollection.cs
- DrawingServices.cs
- XPathDocumentIterator.cs
- complextypematerializer.cs
- StrokeCollectionConverter.cs
- MsmqDiagnostics.cs
- CodeDesigner.cs
- ControlsConfig.cs
- Part.cs
- ConsumerConnectionPointCollection.cs
- ResourceAssociationSetEnd.cs
- WebServiceReceive.cs