N of M Question (Why Use ActivityExecutionContextManager?)

In this post, mstiefel  asked the following:

# re: Implementing the N of M Pattern in WF

Since you are not looping, do you have to use the ActivityExecutionContextManager to generate a new context for the child activities? Couldn't you use the context passed into the Execute method?

Friday, July 06, 2007 7:54 PM by mstiefel

If I were creating a parallel activity, and simply wanted to execute a number of distinct child activities, I would just use the passed in context as you suggest to schedule execution of each of the activities.  The difference here is subtle, and that is I don't have distinct child activities, I have one child activity which I need to clone m times and execute those cloned children separately.  The need to create the context is so that each one of those clones maintains it's own execution context, what variables are where, who is in what state, etc.  This is important while executing, and while after completion in the need where I want to compensate for the individual activities.

This line

 ActivityExecutionContext newContext = aecm.CreateExecutionContext(this.Activities[0]);

is what will cause the activity to be cloned, allowing me to schedule the execution of the clone, and not the template activity (which, incidentally, will never be scheduled, leaving me with m+1  copies of the activity.  This is the same behavior that I get in a While or a Replicator (or the CAG, depending upon how it is configured).  A state machine workflow will do a similar thing as I may re-enter a state multiple times. 

If, instead of allowing a user to specify the list of approvers and dynamically creating the activities, I designed it so that a user would have to drop and configure an activity for each approval (similar to the parallel activity), I would have used code like this:

 // Code to schedule distinct activities in parallel, aka code similar to the parallel activity
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
        foreach (Activity activity in ChildActivities)
        {
            // i is some counter I use to track how many branches there are so I know when
            // I am done
            i++;
            // I'm interested in what happens when this guy closes.
            activity.RegisterForStatusChange(Activity.ClosedEvent, this);
            executionContext.ExecuteActivity(activity);
        }
        return ActivityExecutionStatus.Executing;
}