CompositeActivities: Workflow activities that contain one or more child activities.

Posted on 8/2/2006 @ 4:15 PM in #Vanilla .NET by | Feedback | 5494 views

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 !!

Sound off but keep it civil:

Older comments..


On 8/4/2006 8:50:48 AM Carl said ..
Hi Sahil,

I got as far as getting One..Two..Three..Four, but then you seemed to take an invisible leap into having a parallel activity in there... I can't seem to find anywhere in Studio where I can create this.

Rest of it seems pretty straightforward and neat in a new tech sort of way.

Cheers,

Carl


On 8/4/2006 9:11:57 AM Sahil Malik said ..
Hey Carl,

The parallel activity is yet another Composite activity that ships with the framework. It should be in your toolbox.

Sahil Malik


On 8/4/2006 9:34:51 AM Carl said ..
Hi Sahil,

Thanks for that, maybe it is because I downloaded the Beta 2.2 version of the extensions instead of RC4 (which I assume is the latest), as mentioned here:

http://blibblogblib.blogspot.com/2006/08/microsoft-downloads.html

I'm just about to install the RC4 version, so I guess we'll see.

Cheers,

Carl


On 8/4/2006 1:23:53 PM Sahil Malik said ..
Hmm .. Carl .. I'm working on the version that works with Sharepoint Beta2 .. which I think is older than the one you are working with. Can you please check in reflector if that class is even present in that CTP?

SM


On 6/4/2007 9:11:16 AM Balamurali B said ..
Hi Sahil,

your work on workflows are simply great! I have a question. please clear it out.


I want to cancel a workflow or activity. I have tried with CancelEventHandlerActivity but not working correctly to my expectation. Exactly I want to know, how do I invoke the cancel method/event? Pls. reply me through email.