Beispiel #1
0
        /// <summary>
        /// Start any child activities that need to be run
        /// </summary>
        /// <param name="cag"></param>
        /// <param name="context"></param>
        internal void TriggerChildren(ConditionedActivityGroup cag, ActivityExecutionContext context)
        {
            Debug.Assert(cag != null);
            Debug.Assert(context != null);
#if     LOG
            Log("TriggerChildren on " + cag.QualifiedName);
            cag.CAGState.DumpState("Before TriggerChildren");
#endif

            Dictionary <string, CAGChildStats> childrenStats = cag.CAGState.ChildrenStats;
            // until condition is false, so let's look at all children
            foreach (Activity act in cag.EnabledActivities)
            {
                // do we think this child needs to run?
                if (childrenStats[act.QualifiedName].State != CAGChildState.Pending)
                {
                    continue;
                }

                // find the run-time activity
                Activity activity = GetRuntimeInitializedActivity(context, act);
                if (activity.ExecutionStatus == ActivityExecutionStatus.Initialized)
                {
                    ExecuteChild(cag, activity, context);
                }
            }
#if     LOG
            cag.CAGState.DumpState("After TriggerChildren");
#endif
        }
Beispiel #2
0
        protected override void OnActivityChangeRemove(ActivityExecutionContext executionContext, Activity removedActivity)
        {
            if (executionContext == null)
            {
                throw new ArgumentNullException("executionContext");
            }
            if (removedActivity == null)
            {
                throw new ArgumentNullException("removedActivity");
            }

            if (!removedActivity.Enabled)
            {
                return;
            }

            ConditionedActivityGroup cag = executionContext.Activity as ConditionedActivityGroup;

            Debug.Assert(cag != null);

            // find out the status of the cag

            ConditionedActivityGroupStateInfo state = cag.CAGState;

            if ((cag.ExecutionStatus == ActivityExecutionStatus.Executing) && (state != null))
            {
                state.ChildrenStats.Remove(removedActivity.QualifiedName);
            }
        }
Beispiel #3
0
        protected override void OnWorkflowChangesCompleted(ActivityExecutionContext executionContext)
        {
            if (executionContext == null)
            {
                throw new ArgumentNullException("executionContext");
            }

            // find out the status of the cag
            ConditionedActivityGroup currentActivity = executionContext.Activity as ConditionedActivityGroup;

            // if CAG is executing... fire the conditions on the net result
            if (currentActivity.ExecutionStatus == ActivityExecutionStatus.Executing)
            {
                // but hold on, a derived cag could be applying model changes before it
                // "really" starts executing the activities. In that case it will evaluate
                // the conditions later, at the appropriate time.
                ConditionedActivityGroupStateInfo state = currentActivity.CAGState;
                if ((state != null) && (!state.Testing))
                {
                    // fire away...  fire away... said the CAG
                    if (this.EvaluateConditions(currentActivity, executionContext))
                    {
                        // CAG until indicates we are done, so no children execute
                        this.Cleanup(currentActivity, executionContext);
                    }
                    else
                    {
                        // start any pending activity required
                        this.TriggerChildren(currentActivity, executionContext);
                    }
                }
            }
        }
Beispiel #4
0
        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;
            }

            ConditionedActivityGroup currentActivity = executionContext.Activity as ConditionedActivityGroup;

            Debug.Assert(currentActivity != null);

            ConditionedActivityGroupStateInfo state = currentActivity.CAGState;

            if (currentActivity.ExecutionStatus == ActivityExecutionStatus.Executing && state != null)
            {
                Debug.Assert(currentActivity == addedActivity.Parent, "Attempting to add wrong activity to CAG");
                state.ChildrenStats[addedActivity.QualifiedName] = new CAGChildStats();
            }
        }
Beispiel #5
0
        internal bool Cleanup(ConditionedActivityGroup cag, ActivityExecutionContext context)
        {
            // the completion condition has fired, or we are canceling
            // either way, we want to cleanup
            ConditionedActivityGroupStateInfo state = cag.CAGState;

            state.Completed = true;

            // cancel any children currently running
            bool childrenActive = false;
            Dictionary <string, CAGChildStats> childrenStats = state.ChildrenStats;

            foreach (Activity act in cag.EnabledActivities)
            {
                // reset any Pending Execution for all child activity
                if (childrenStats[act.QualifiedName].State == CAGChildState.Pending)
                {
                    childrenStats[act.QualifiedName].State = CAGChildState.Idle;
                }

                // find the run-time activity
                ActivityExecutionContext childContext = GetChildExecutionContext(context, act, false);
                if (childContext != null)
                {
                    // child must be running somewhere
                    Activity activity = GetRuntimeInitializedActivity(context, act);
                    switch (activity.ExecutionStatus)
                    {
                    case ActivityExecutionStatus.Executing:
                        // schedule cancellation on child
                        childContext.CancelActivity(activity);
                        childrenActive = true;
                        break;

                    case ActivityExecutionStatus.Canceling:
                    case ActivityExecutionStatus.Faulting:
                        childrenActive = true;
                        break;

                    case ActivityExecutionStatus.Closed:
                        CleanupChildAtClosure(context, activity);
                        break;

                    default:
                        // unhook our handler
                        // others will be removed when we get the complete/cancel notification
                        act.UnregisterForStatusChange(Activity.ClosedEvent, this);
                        break;
                    }
                }
            }

            // if the CAG is quiet, we are all done
            if (!childrenActive)
            {
                context.CloseActivity();
            }
            return(!childrenActive);
        }
        private void ExecuteChild(ConditionedActivityGroup cag, Activity childActivity, ActivityExecutionContext context)
        {
            ActivityExecutionContext context2 = GetChildExecutionContext(context, childActivity, true);

            cag.CAGState.ChildrenStats[childActivity.QualifiedName].State = CAGChildState.Excuting;
            context2.Activity.RegisterForStatusChange(Activity.ClosedEvent, this);
            context2.ExecuteActivity(context2.Activity);
        }
Beispiel #7
0
        internal ConditionedActivityGroupStateInfo(ConditionedActivityGroup cag)
        {
            int len = cag.EnabledActivities.Count;

            this.childActivityStats = new Dictionary <string, CAGChildStats>(len);
            foreach (Activity act in cag.EnabledActivities)
            {
                this.childActivityStats[act.QualifiedName] = new CAGChildStats();
            }
        }
Beispiel #8
0
        public override ValidationErrorCollection Validate(ValidationManager manager, object obj)
        {
            ValidationErrorCollection validationErrors = base.Validate(manager, obj);

            ConditionedActivityGroup conditionedActivityGroup = obj as ConditionedActivityGroup;

            if (conditionedActivityGroup == null)
            {
                throw new ArgumentException(SR.GetString(SR.Error_UnexpectedArgumentType, typeof(ConditionedActivityGroup).FullName), "obj");
            }

            return(validationErrors);
        }
        internal bool Cleanup(ConditionedActivityGroup cag, ActivityExecutionContext context)
        {
            ConditionedActivityGroupStateInfo cAGState = cag.CAGState;

            cAGState.Completed = true;
            bool flag = false;
            Dictionary <string, CAGChildStats> childrenStats = cAGState.ChildrenStats;

            foreach (Activity activity in cag.EnabledActivities)
            {
                if (childrenStats[activity.QualifiedName].State == CAGChildState.Pending)
                {
                    childrenStats[activity.QualifiedName].State = CAGChildState.Idle;
                }
                ActivityExecutionContext context2 = GetChildExecutionContext(context, activity, false);
                if (context2 != null)
                {
                    Activity runtimeInitializedActivity = this.GetRuntimeInitializedActivity(context, activity);
                    switch (runtimeInitializedActivity.ExecutionStatus)
                    {
                    case ActivityExecutionStatus.Executing:
                    {
                        context2.CancelActivity(runtimeInitializedActivity);
                        flag = true;
                        continue;
                    }

                    case ActivityExecutionStatus.Canceling:
                    case ActivityExecutionStatus.Faulting:
                    {
                        flag = true;
                        continue;
                    }

                    case ActivityExecutionStatus.Closed:
                    {
                        this.CleanupChildAtClosure(context, runtimeInitializedActivity);
                        continue;
                    }
                    }
                    activity.UnregisterForStatusChange(Activity.ClosedEvent, this);
                }
            }
            if (!flag)
            {
                context.CloseActivity();
            }
            return(!flag);
        }
 private bool AllChildrenQuiet(ConditionedActivityGroup cag, ActivityExecutionContext context)
 {
     if (context == null)
     {
         throw new ArgumentNullException("context");
     }
     foreach (ActivityExecutionContext context2 in context.ExecutionContextManager.ExecutionContexts)
     {
         if (cag.GetActivityByName(context2.Activity.QualifiedName, true) != null)
         {
             return(false);
         }
     }
     return(true);
 }
        internal void TriggerChildren(ConditionedActivityGroup cag, ActivityExecutionContext context)
        {
            Dictionary <string, CAGChildStats> childrenStats = cag.CAGState.ChildrenStats;

            foreach (Activity activity in cag.EnabledActivities)
            {
                if (childrenStats[activity.QualifiedName].State == CAGChildState.Pending)
                {
                    Activity runtimeInitializedActivity = this.GetRuntimeInitializedActivity(context, activity);
                    if (runtimeInitializedActivity.ExecutionStatus == ActivityExecutionStatus.Initialized)
                    {
                        this.ExecuteChild(cag, runtimeInitializedActivity, context);
                    }
                }
            }
        }
        private bool EvaluateChildConditions(ConditionedActivityGroup cag, Activity child, ActivityExecutionContext context)
        {
            bool flag;
            ConditionedActivityGroupStateInfo cAGState = cag.CAGState;

            try
            {
                cAGState.Testing = true;
                ActivityCondition condition = (ActivityCondition)child.GetValue(WhenConditionProperty);
                flag = (condition != null) ? condition.Evaluate(child, context) : (cAGState.ChildrenStats[child.QualifiedName].ExecutedCount == 0);
            }
            finally
            {
                cAGState.Testing = false;
            }
            return(flag);
        }
Beispiel #13
0
        private void ExecuteChild(ConditionedActivityGroup cag, Activity childActivity, ActivityExecutionContext context)
        {
            Debug.Assert(cag != null);
            Debug.Assert(childActivity != null);
            Debug.Assert(context != null);
            Debug.Assert(childActivity.ExecutionStatus == ActivityExecutionStatus.Initialized);
#if     LOG
            Log("ExecuteChild " + childActivity.QualifiedName + " inside " + cag.QualifiedName);
#endif
            ActivityExecutionContext childContext = GetChildExecutionContext(context, childActivity, true);
            cag.CAGState.ChildrenStats[childActivity.QualifiedName].State = CAGChildState.Excuting;

            // subscribe for child closure
            childContext.Activity.RegisterForStatusChange(Activity.ClosedEvent, this);

            // execute child in inner context
            childContext.ExecuteActivity(childContext.Activity);
        }
Beispiel #14
0
        bool AllChildrenQuiet(ConditionedActivityGroup cag, ActivityExecutionContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            // if there are any execution contexts, 1 or more children still doing something
            foreach (ActivityExecutionContext activeContext in context.ExecutionContextManager.ExecutionContexts)
            {
                if (cag.GetActivityByName(activeContext.Activity.QualifiedName, true) != null)
                {
                    return(false);
                }
            }

            // no children
            return(true);
        }
 protected override void OnActivityChangeRemove(ActivityExecutionContext executionContext, Activity removedActivity)
 {
     if (executionContext == null)
     {
         throw new ArgumentNullException("executionContext");
     }
     if (removedActivity == null)
     {
         throw new ArgumentNullException("removedActivity");
     }
     if (removedActivity.Enabled)
     {
         ConditionedActivityGroup          activity = executionContext.Activity as ConditionedActivityGroup;
         ConditionedActivityGroupStateInfo cAGState = activity.CAGState;
         if ((activity.ExecutionStatus == ActivityExecutionStatus.Executing) && (cAGState != null))
         {
             cAGState.ChildrenStats.Remove(removedActivity.QualifiedName);
         }
     }
 }
Beispiel #16
0
        /// <summary>
        /// Evaluate the While condition for a particular child of the CAG
        /// If no While condition, it becomes "execute once"
        /// </summary>
        /// <param name="cag"></param>
        /// <param name="child"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        private bool EvaluateChildConditions(ConditionedActivityGroup cag, Activity child, ActivityExecutionContext context)
        {
#if     LOG
            Log("EvaluateChildConditions on activity " + child.QualifiedName + " inside " + cag.QualifiedName);
#endif
            // determine the result of the when condition (evaluate once if not specified)
            ConditionedActivityGroupStateInfo state = cag.CAGState;
            try
            {
                state.Testing = true;
                ActivityCondition whenCondition = (ActivityCondition)child.GetValue(ConditionedActivityGroup.WhenConditionProperty);
                return((whenCondition != null)
                    ? whenCondition.Evaluate(child, context)
                    : (state.ChildrenStats[child.QualifiedName].ExecutedCount == 0));
            }
            finally
            {
                state.Testing = false;
            }
        }
 internal bool EvaluateConditions(ConditionedActivityGroup cag, ActivityExecutionContext context)
 {
     if (cag.CAGState.Completed)
     {
         return(false);
     }
     if ((cag.UntilCondition == null) || !cag.UntilCondition.Evaluate(cag, context))
     {
         int num = 0;
         Dictionary <string, CAGChildStats> childrenStats = cag.CAGState.ChildrenStats;
         foreach (Activity activity in cag.EnabledActivities)
         {
             if (childrenStats[activity.QualifiedName].State == CAGChildState.Excuting)
             {
                 num++;
             }
             else
             {
                 Activity runtimeInitializedActivity = this.GetRuntimeInitializedActivity(context, activity);
                 if (this.EvaluateChildConditions(cag, runtimeInitializedActivity, context))
                 {
                     num++;
                     childrenStats[activity.QualifiedName].State = CAGChildState.Pending;
                 }
             }
         }
         if (num > 0)
         {
             return(false);
         }
         if (cag.UntilCondition != null)
         {
             throw new InvalidOperationException(SR.GetString("Error_CAGQuiet", new object[] { cag.QualifiedName }));
         }
     }
     return(true);
 }
        protected override void OnWorkflowChangesCompleted(ActivityExecutionContext executionContext)
        {
            if (executionContext == null)
            {
                throw new ArgumentNullException("executionContext");
            }
            ConditionedActivityGroup activity = executionContext.Activity as ConditionedActivityGroup;

            if (activity.ExecutionStatus == ActivityExecutionStatus.Executing)
            {
                ConditionedActivityGroupStateInfo cAGState = activity.CAGState;
                if ((cAGState != null) && !cAGState.Testing)
                {
                    if (this.EvaluateConditions(activity, executionContext))
                    {
                        this.Cleanup(activity, executionContext);
                    }
                    else
                    {
                        this.TriggerChildren(activity, executionContext);
                    }
                }
            }
        }
        internal void HandleEvent(ActivityExecutionContext context, SubscriptionEventArg e)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (e == null)
            {
                throw new ArgumentNullException("e");
            }
            ConditionedActivityGroup activity = context.Activity as ConditionedActivityGroup;

            if (activity == null)
            {
                throw new ArgumentException(SR.GetString("Error_InvalidCAGActivityType"), "activity");
            }
            if (activity.ExecutionStatus != ActivityExecutionStatus.Closed)
            {
                EventType subscriptionType = e.SubscriptionType;
                ActivityExecutionStatusChangedEventArgs args = (ActivityExecutionStatusChangedEventArgs)e.Args;
                bool flag = false;
                Dictionary <string, CAGChildStats> childrenStats = activity.CAGState.ChildrenStats;
                if (childrenStats.ContainsKey(args.Activity.QualifiedName))
                {
                    if (args.ExecutionStatus != ActivityExecutionStatus.Executing)
                    {
                        childrenStats[args.Activity.QualifiedName].State = CAGChildState.Idle;
                    }
                    if (args.ExecutionStatus == ActivityExecutionStatus.Closed)
                    {
                        CAGChildStats local1 = childrenStats[args.Activity.QualifiedName];
                        local1.ExecutedCount++;
                    }
                    try
                    {
                        if (activity.ExecutionStatus == ActivityExecutionStatus.Executing)
                        {
                            flag = this.EvaluateConditions(activity, context);
                        }
                    }
                    finally
                    {
                        this.CleanupChildAtClosure(context, args.Activity);
                    }
                }
                else if (activity.ExecutionStatus == ActivityExecutionStatus.Executing)
                {
                    flag = this.EvaluateConditions(activity, context);
                }
                if (flag)
                {
                    this.Cleanup(activity, context);
                }
                else if (activity.CAGState.Completed)
                {
                    if (this.AllChildrenQuiet(activity, context))
                    {
                        context.CloseActivity();
                    }
                }
                else
                {
                    this.TriggerChildren(activity, context);
                }
            }
        }
Beispiel #20
0
        /// <summary>
        /// Evaluate the conditions on the CAG
        /// </summary>
        /// <param name="cag"></param>
        /// <param name="context"></param>
        /// <returns>True if CAG is complete (UNTIL == true, or no UNTIL and no children execute), false otherwise</returns>
        internal bool EvaluateConditions(ConditionedActivityGroup cag, ActivityExecutionContext context)
        {
            Debug.Assert(cag != null);
            Debug.Assert(context != null);
#if     LOG
            Log("EvaluateConditions on " + cag.QualifiedName);
            cag.CAGState.DumpState("Before EvaluateConditions");
#endif
            // if we've already decided to quit this CAG, don't do anything
            if (cag.CAGState.Completed)
            {
                return(false);
            }

            // if the cag has an UNTIL condition, execute it
            if ((cag.UntilCondition != null) && cag.UntilCondition.Evaluate(cag, context))
            {
                // UNTIL condition says we're done, no need to look at children
#if     LOG
                Log("Until condition is true");
#endif
                return(true);
            }

            // until condition is false, so let's look at all children
            int childExecuting = 0; // keep track of children executing
            Dictionary <string, CAGChildStats> childrenStats = cag.CAGState.ChildrenStats;
            foreach (Activity act in cag.EnabledActivities)
            {
                // if we think the child is executing, do nothing
                if (childrenStats[act.QualifiedName].State == CAGChildState.Excuting)
                {
                    ++childExecuting;
                    continue;
                }

                // find the run-time activity
                Activity activity = GetRuntimeInitializedActivity(context, act);
                // should it execute?
                if (EvaluateChildConditions(cag, activity, context))
                {
                    ++childExecuting;
                    childrenStats[act.QualifiedName].State = CAGChildState.Pending;
                }
            }
#if     LOG
            cag.CAGState.DumpState("After EvaluateConditions");
#endif

            // if any work to do, CAG not yet done
            if (childExecuting > 0)
            {
                return(false);
            }

            // CAG is quiet (nothing more to do)
            // if specified an UNTIL condition but we have nothing to do
            if (cag.UntilCondition != null)
            {
#if     LOG
                Log("CAG quiet, but UNTIL condition is false, so error time");
#endif
                throw new InvalidOperationException(SR.GetString(SR.Error_CAGQuiet, cag.QualifiedName));
            }
#if     LOG
            Log("CAG quiet");
#endif
            return(true);
        }
Beispiel #21
0
        internal void HandleEvent(ActivityExecutionContext context, SubscriptionEventArg e)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (e == null)
            {
                throw new ArgumentNullException("e");
            }

            ConditionedActivityGroup cag = context.Activity as ConditionedActivityGroup;

            if (cag == null)
            {
                throw new ArgumentException(SR.GetString(SR.Error_InvalidCAGActivityType), "activity");
            }

            // Already done the cleanup from another child's signalling
            if (cag.ExecutionStatus == ActivityExecutionStatus.Closed)
            {
                return;
            }

            if (e.SubscriptionType != EventType.StatusChange)
            {
                // split into seperate test to keep FxCop happy (only place SubscriptionType used)
                Debug.Assert(false, "This CAG activity handler does not handle this event");
            }
            ActivityExecutionStatusChangedEventArgs args1 = (ActivityExecutionStatusChangedEventArgs)e.Args;

#if     LOG
            Log("HandleEvent for " + cag.QualifiedName);
            Log("event = " + e.ToString());
            Log("activity = " + args1.Activity.QualifiedName);
#endif

            bool timeToQuit = false;

            // is this event is for an immediate child?
            Debug.Assert(cag == args1.Activity.Parent, "Received event for non-child of CAG");
            Dictionary <string, CAGChildStats> childrenStats = cag.CAGState.ChildrenStats;

            // it is possible that dynamic update has removed the child before we get the closed event
            // if that is the case, we don't need to update it's stats since it's not there
            if (childrenStats.ContainsKey(args1.Activity.QualifiedName))
            {
                // update our state about the child
                if (args1.ExecutionStatus != ActivityExecutionStatus.Executing)
                {
                    childrenStats[args1.Activity.QualifiedName].State = CAGChildState.Idle;
                }

                // @undone: this will break if scopes move to "Delayed" closing after Completed.
                if (args1.ExecutionStatus == ActivityExecutionStatus.Closed)
                {
                    childrenStats[args1.Activity.QualifiedName].ExecutedCount++;
                }

                try
                {
                    // re-evaluate the conditions on any status change, as long as the CAG is still executing
                    if (cag.ExecutionStatus == ActivityExecutionStatus.Executing)
                    {
                        timeToQuit = EvaluateConditions(cag, context);
                    }
                }
                finally
                {
                    // get rid of the child that just completed
                    // do this in the finally so that the child is cleaned up,
                    // even if EvaluateConditions throws beause the CAG is stalled
                    CleanupChildAtClosure(context, args1.Activity);
                }
            }
            else
            {
                // child has been removed
                // we still need to see if the CAG is done, provided we are still executing
                if (cag.ExecutionStatus == ActivityExecutionStatus.Executing)
                {
                    timeToQuit = EvaluateConditions(cag, context);
                }
            }

            // is the CAG just completed?
            if (timeToQuit)
            {
                Cleanup(cag, context);
            }
            else if (cag.CAGState.Completed)
            {
                // if the CAG is simply waiting for all children to complete, see if this is the last one
                if (AllChildrenQuiet(cag, context))
                {
                    // Mark the CAG as closed, if it hasn't already been marked so.
                    context.CloseActivity();
                }
            }
            else
            {
                // CAG not done, so see if any children need to start
                TriggerChildren(cag, context);
            }
        }