Execute a child activity and wait for the results
I came into a situation where I had to selectively
execute a child activity. I wanted the activity to execute it's first child,
wait for the results and then based on those results execute the next child.
The reason for this was that I wanted to write an Ifelse activity which takes
activities as conditions (Instead of making my business user write code for code
conditions) and based on the conditions results execute the rest of the branch.
I'll upload the complete IfElseActivity ASAP.
Step 1:
In order to execute a child activity, the parent activity has to implement
the IActivityEventListener<ActivityExecutionStatusChangedEventArgs>
interface. This enables it to subscribe to execution events
executed in contexts spawned by the parent. This post gives some insight on
contexts: http://blogs.msdn.com/advancedworkflow/archive/2006/03/21/557121.aspx
Step 2:
protected override ActivityExecutionStatus Execute(ActivityExecutionContext
executionContext)
{
//Spawn
the context (Execution sphere for your child activity)
ActivityExecutionContext context =
executionContext.ExecutionContextManager.CreateExecutionContext(EnabledActivities[theChildIndex]);
//Register to get an event on this activity if the child
activity's status is set to closed
context.Activity.RegisterForStatusChange(ClosedEvent, this);
//Execute the root activity of the context
context.ExecuteActivity(context.Activity);
return ActivityExecutionStatus.Executing; //Important to return Executing because the child will only
execute after this method has finished
}
You can only spawn an ActivityExecutionContext for direct
children on the container activity.
Step 3:
In the OnEvent method which was implemented from the
IActivityEventListener interface, we do the following:
void IActivityEventListener<ActivityExecutionStatusChangedEventArgs>.OnEvent(object sender, ActivityExecutionStatusChangedEventArgs e)
{
if (null == sender)
throw new ArgumentNullException("sender");
if (null == e)
throw new ArgumentException("e");
//This cis the spawned context with the child activity as the root
ActivityExecutionContext context = sender as ActivityExecutionContext;
if (null == context)
throw new ArgumentException("The sender must be an ActivityExecutionContext", "sender");
//This event handler will be triggered for every subscribed status change
if (e.ExecutionStatus == ActivityExecutionStatus.Closed)
{
//get a reference to the root activity of the context (Your child activity)
MyActivity myActivity = e.Activity as myActivity;
//Do whatever you want to do with the activity - something more meaningful as this :)
if (myActivity.Bla == "Blie")
{
Console.WriteLine("Bla was Blie");
}
//Ensure that this activity finishes executing and that the child activity is closed
e.Activity.UnregisterForStatusChange(ClosedEvent, this);
ActivityExecutionContextManager manager = context.ExecutionContextManager;
manager.CompleteExecutionContext(manager.GetExecutionContext(e.Activity));
context.CloseActivity();
}
}
Reasons to do this would be to execute a child activity more
than once, or as in my scenarrio to provide an ifelse branch with activities as
the condition.
powered by IMHO 1.3