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);
                }
            }
        }
예제 #2
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);
            }
        }