.. so this activity is like a pregnant piglet - it contains one or more pigs inside of it !! :)
When you create a workflow, you have a choice picking from a number of activities that are a part of the framework, or you can write your own. There are a few exotic activities, such as a compensating activity, or the TransactionScope activity. I call them exotic because they are rather funky – but we’ll cover them in detail in future blogposts.
This blogpost talks more about CompositeActivities. CompositeActivities are those activities which is an activity that implements it’s logic as one or more child activities. CompositeActivities inherit from the System.Workflow.ComponentModel.CompositeActivity class and has a property called Activities which contains the various child activities.
So, let us expand the “Hello World” example you’ve already seen in my last blog post, and try and understand composite activities and their behavior.
Various activities execute in a workflow. In my last example, I showed a rather simple activity being executed in a sequence. Activities can execute out of sequence as well.
For instance, check out the class diagram below:

The above class diagram is admittedly simple, but consider this, a sequence activity always ensures that the activities execute in the defined sequence. Parallel activities on the other hand, do not guarantee that.
But both are composite activities since, both sequence activities and parallel activities really run a bunch of other activities.
So let us write up a simple activity to demonstrate this. Here is the code for the activity.
public partial class MyActivity: Activity
{
public MyActivity()
{
InitializeComponent();
}
private string text;
public string Text
{
get { return text; }
set { text = value; }
}
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
Console.WriteLine(text);
return ActivityExecutionStatus.Closed;
}
}
(Did you note that I returned ActivityExecutionStatus.Closed? Well – there’s a good reason for that – will talk about that soon).
Using this activity is rather simple. You can use it using the following code snippet,
<SequentialWorkflowActivity ..some other goo that I took out..>
<ns0:MyActivity Text="One" x:Name="myActivity1" />
</SequentialWorkflowActivity>
This looks like the below in design view.

When you run this, it prints “One” at the console, because hey that is what our activity does.
Now let us make this workflow a bit more involved. Let us say, I am going to execute four of these activities in sequence. My workflow now looks like this.
<SequentialWorkflowActivity .. some goo that I took out ..>
<ns0:MyActivity Text="One" x:Name="myActivity1" />
<ns0:MyActivity Text="Two" x:Name="myActivity2" />
<ns0:MyActivity Text="Three" x:Name="myActivity3" />
<ns0:MyActivity Text="Four" x:Name="myActivity4" />
</SequentialWorkflowActivity>
When you run this workflow, it will produce One, Two, Three, Four in sequence.
Now let us split this into two parallel activities instead. So our workflow now looks like this.

The xoml now looks like this.
<ParallelActivity x:Name="parallelActivity1">
<SequenceActivity x:Name="sequenceActivity1">
<ns0:MyActivity Text="One" x:Name="myActivity1" />
<ns0:MyActivity Text="Two" x:Name="myActivity2" />
</SequenceActivity>
<SequenceActivity x:Name="sequenceActivity2">
<ns0:MyActivity Text="Three" x:Name="myActivity3" />
<ns0:MyActivity Text="Four" x:Name="myActivity4" />
</SequenceActivity>
</ParallelActivity>
Now check this out, What will the above print?
Now order execution between various branches of a parallel activity is not guaranteed, so all of the following are legit outputs.
One
Two
Three
Four
Or
One
Three
Two
Four
Or
Three
One
Two
Four
What is not legit is
Two
One
Three
Four
Why? Because the order execution is guaranteed inside a sequence activity, but not inside a parallel activity. If the parallel activity was a part of execution of larger sequence activity, then the order of execution inside of parallel activity is still not guaranteed, but the parallel activity as a whole will fall within a sequence. Thus, the activity after the parallel activity does not get executed unless all activities within all branches of the parallel activitity get executed.
So this brings up the obvious question of, how the heck is the state machine maintained inside of a workflow?
Well that is where the ActivityExecutionStatus and ActivityExecutionContext come into play. I’ll be talkin’ about that next. Stay tuned !!