WF dynamic changes are a performance disaster
I wanted to build a workflow which has 3 parallel branches that executes continuously
Each branch holds a list of activities.
What is interesting about this workflow is the fact that activities can move from one branch to another.
I found out that whenever an activity moves CPU increases drastically.
I used the following code and found out interesting phenomenon:
1. Even if there is no change in the workflow (no activities are added nor removed) there is a huge spike in CPU !!!
2. This is the interesting part: If you continue to perform changes (let us say once a minute an activity is moved) the CPU spike will be greater every time. In my system I created a WF change every few seconds and after few minutes the I experienced 100% CPU spikes!!!
This is amazing!!! It means that someone did not release resources …
It is expectable that one operation influences another one.
Let us see some code:
// 1. Create a WorkflowChanges class to author dynamic change
changes = new WorkflowChanges(this);
CompositeActivity ActiveTestsComposite = changes.TransientWorkflow.GetActivityByName("ActiveTestsActivities") as CompositeActivity;
//2. Add the activities to the branch (they all inherit from TestBase)
foreach (TestBase test in TestsToAdd)
{
//we want to create the exact type of test.
TestBase NewTest = Activator.CreateInstance(test.GetType()) as TestBase;
. . .
ActiveTestsComposite.Activities.Add(NewTest);
test.Dispose();
AddFlag = true;
}
// 3. Remove the activities to remove
foreach (TestBase test in TestsToRemove)
{
ActiveTestsComposite.Activities.RemoveAll(delegate(Activity tst)
{ return ((tst as TestBase).TestName == test.TestName); });
removeFlag = true;
}
try
{
// 4. apply transient changes to instance – Here CPU just booms
this.ApplyWorkflowChanges(changes);
}
catch (WorkflowValidationFailedException ex) { ... }
So the result is:
1. Never use Workflow dynamic changes capabilities repeatedly
2. Try to avoid WF dynamic changes - They cost too much.
What was my solution you ask?
I created an activity that read a list of objects (in our case activities) and call their execute method.
These lists can be easily handled like a normal collection.
In each branch I put one such activity and dynamically changed the lists.
Now the Workflow stays the same. No CPU spikes.
We are talking about a major bug (I tried this in VS 2008 Beta 2) and it was not fixed. Maybe someone will read this and. . .
Manu Cohen-Yashar