![]() ![]() | ||||
HomeShow ChangesEditPrintRecent ChangesSubscriptionsLost and FoundFind ReferencesRename
History 14-5-2008 11:52:3414-5-2008 11:47:4814-5-2008 11:46:3514-5-2008 11:45:01 | The ReplicatorActivity is one of the more interesting Workflow Foundation activities to work with when you have a collection of data and want to iterate over each item. Basically just think of it as a For Each statement in regular code. To demonstrate the behavior I have created a very small workflow that looks like this in the designer:
Or in case you prefer the XOML like this:
<SequentialWorkflowActivity x:Class="WorkflowConsoleApplication5.Workflow1"
x:Name="Workflow1"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow">
<ReplicatorActivity x:Name="replicatorActivity1"
ChildInitialized="SetupChildData"
Initialized="SetupData"
ExecutionType="Sequence">
<ReplicatorActivity.UntilCondition>
<CodeCondition Condition="RepeatUntill" />
</ReplicatorActivity.UntilCondition>
<CodeActivity x:Name="codeActivity1"
ExecuteCode="codeActivity1_ExecuteCode" />
</ReplicatorActivity>
</SequentialWorkflowActivity>
The codebehind file I used looks like this:
Public Class Workflow1
Inherits SequentialWorkflowActivity
Private Sub codeActivity1_ExecuteCode(ByVal sender As Object, _
ByVal e As EventArgs)
Dim current As CodeActivity = sender
Dim data = GetCurrentData(current.Parent)
Console.WriteLine("The data is '{0}'", data)
End Sub
Private Sub SetupData(ByVal sender As Object, _
ByVal e As EventArgs)
Dim replicator As ReplicatorActivity = sender
Dim data() As String = _
{"One", "Two", "Stop here", "Three"}
replicator.InitialChildData = data
End Sub
Private Sub RepeatUntill(ByVal sender As Object, _
ByVal e As ConditionalEventArgs)
Dim replicator As ReplicatorActivity = sender
Dim data = GetCurrentData(sender)
Console.WriteLine("Testing with data '{0}'", data)
If data = "Stop here" Then
e.Result = True
ElseIf replicator.AllChildrenComplete Then
e.Result = True
End If
End Sub
Private Sub SetupChildData(ByVal sender As Object, _
ByVal e As ReplicatorChildEventArgs)
Console.WriteLine("Starting child with '{0}'", _
e.InstanceData)
End Sub
Private Function GetCurrentData(ByVal sender As Object)
Dim replicator As ReplicatorActivity = sender
Dim result = replicator.CurrentChildData(replicator.CurrentIndex)
Return result
End Function
End Class
Using the without an UntilCondition is actually quite simple. The main thing to be aware of the ExecutionType property. In this case I didn't set it and it defaults to Sequence. This means that each iteration comes after the next iteration and we can use the CurrentIndex and CurrentChildData to retrieve the piece of data we are working with. When we set the ExecutionType to Parallel the ReplicatorActivity behaves very different. In that case each branch is started at the same time so the CurrentIndex, which is scoped to the ReplicatorActivity, doesn't help you. In fact it will return the last item of the collection every time you try. In the case of parallel execution the way to get at the data is the ChildInitialized event. This event has a parameter of type ReplicatorChildEventArgs which in turn contains a property InstanceData which is the data this iteration is going to work with. its your responsibility to pass this InstanceData on to the activity inside the ReplicatorActivity. The usual thing to do here is create a custom, possibly sequence, activity with an extra property to hold the data and store it there in the ChildInitialized event. There are a few interesting, and unexpected, thing to be a aware of when you use an UntilCondition with a ReplicatorActivity. When I run this simple test workflow I receive the following output:
There are a couple of interesting things to note:
Removing the test for the "Stop here" in the UntilCondition result in the following output:
As you can see there is one additional UntilCondition at the end at which time the AllChildrenComplete property is set to true. | Wiki Usage
This wiki site is supposed to be a shared resource. As a shared resource everyone is encouraged to add new content or modify existing content! Enjoy the WF wiki. Recent Topics
| ||