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); } } }
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); } }