Partilhar via


Dynamic Update 101 for Windows Workflow Foundation

One of the really cool features of Windows Workflow Foundation is the ability to dynamically update a running workflow by inserting new activities or changing the properties of existing activities. All of this is done at runtime and really opens up some cool possibilities when you start looking at how you could apply this feature. As an example, let's say you created a document review state machine workflow. You have the solution up and running and things are going smoothly. Being the keen observer/architect you are, you added the ability to add/remove different people to/from the review cycle. So, when the time comes that Employee X who was just hired on as an editor needs to be involved in the document reviews that go on, you just dynamically update the workflow and things proceed while you sit back and watch it in action. Ok, so I flourished that example a little, but my point here is to get you thinking about how you can use the Dynamic Update feature in Windows Workflow Foundation and the myriad of possibilities it opens up.

I decided to just create a quick and dirty example on using Dynamic Updates so here goes. To begin with, I created a Sequential Workflow Console Application (one of the project templates supplied with Windows Workflow Foundation). In this workflow, I added a While activity, a Sequence activity inside the While activity, and 2 Code activities inside the Sequence activity. Here's what it looks like:

I then added 2 simple handlers for the 2 Code activities each of which do a simple Console.WriteLine. So, the workflow itself is finished (remember, this is Dynamic Update 101 so I don't want to lose you in a vast oasis of Workflow activities).

Since I started with the Sequential Workflow Console Application, a default host was created for me. When you want to apply dynamic updates to a running workflow, you first need to obtain a WorkflowChanges object. You can do this by simply instantiating that new object passing in the IRootActivity of your already running workflow. So, how do you do this? Simple. When you call the WorkflowRuntime's StartWorkflow method, it returns a WorkflowInstance object. To get the IRootActivity of that instance, just call the GetWorkflowDefintion() method. So, to create a WorkflowChanges object, use (where wfInstance is my WorkflowInstance object):

 WorkflowChanges wfChanges = new WorkflowChanges(wfInstance.GetWorkflowDefinition());

I should mention what's going on here when you do this. If you think about how database transaction work, you obtain the database data, make changes and then apply those changes to complete the transaction. In other words, you obtain a "copy" of the data, make changes on that copy and then once you have made all the changes you commit to update the real data. Windows Workflow Foundation follows the same pattern. When you obtain a WorkflowChanges object, you are really obtaining a copy of the running workflow instance. You can make changes to that workflow until the cows come home (doh! a writer using a cliché) but the changes won't happen on the real instance until you apply them.

Back to our sample. Now that I have a WorkflowChanges object, I can start making some changes. My goal is to insert a new Code activity between the 2 existing code activities. We first have to navigate the workflow's object model to get to our insertion point. Since the 2 existing Code activities (and the Delay) activity are contained within the Sequence activity, we just need to get the Sequence activity. Here's how that's done:

 // drill down to code 2 activity
While whileActivity = wfChanges.TransientWorkflow.Activities["while1"] as While;
Sequence seqActivity = whileActivity.Activities["sequence1"] as Sequence;

Now that we have our target Parent activity, we can create the new Code activity, insert it between the 2 existing Code activities and then save the WorkflowChanges. Creating a new Code activity is a trivial matter. After creating a new instance, add an event handler to the ExecuteCode event. Just like the other Code activities, our code handler will do a simple Console.WriteLine. To insert the activity, you can use the Insert method from the Activities collection of the Sequence activity you obtained above. This method accepts an index denoting where to insert the new activity followed by the activity to insert. Other methods exist for the Activities collection that mirror that of a typical .NET collection (e.g. Add). After that, call the Save method defined on the WorkflowChanges object and apply the changes to the running workflow instance by calling the ApplyWorkflowChanges method from the WorkflowInstance object passing your WorkflowChanges object. Here's the code showing how to do everything just explained:

 // create new code activity to insert
Code newCode = new Code();
newCode.ExecuteCode += new EventHandler(codeActivity_ExecuteCode);

// insert new code activity preceding the code2 activity
seqActivity.Activities.Insert(1, newCode);

// save and apply the workflow changes
wfChanges.Save();

wfInstance.ApplyWorkflowChanges(wfChanges);

There you have it. When you run your project, you should see output similar to the following:

 Executing code block 1
New code block executing
Executing code block 2
Executing code block 1
New code block executing
Executing code block 2
Executing code block 1
New code block executing
Executing code block 2
Executing code block 1
New code block executing
Executing code block 2
Executing code block 1
New code block executing
Executing code block 2
Press any key to continue . . .

As I said, Dynamic Update 101 which is a simple way to enter and start learning this cool feature of Windows Workflow Foundation.

Click here to download the entire project source code

If you have any questions/comments/requests just fire an email off to me.

-Mark

Comments

  • Anonymous
    January 30, 2006
    Good one for beginners who are looking to update WF dynamically.
    Thanks

  • Anonymous
    March 21, 2006
    The comment has been removed

  • Anonymous
    April 11, 2006
    HI MarkIf my workflow is not imperative as shown above and i am creating a workflow from XOML and during runtime i wanted to change it...meaning dynamic updates .. how do i accomplish that .how to capture the workflow changes object.. should i again recompile the xoml ?? will you be able to give an code example for this. please mail me at Bprasad@covansys.comThanks in advance for the help

  • Anonymous
    June 15, 2006
    in Dynamic update the workflow completed event in workflow runtime rised twice one for orginal workflow other for added activities can u tell me why completed event rise two times..

  • Anonymous
    October 30, 2006
    I think using Windows Workflows has a learning curve and it's simpler to implement my own workflow control. Either way, that's just my opinion. Perhaps after I use it for a while, I'll change my mind.

  • Anonymous
    December 30, 2007
    PingBack from http://restaurants.247blogging.info/?p=277

  • Anonymous
    June 02, 2009
    PingBack from http://outdoorceilingfansite.info/story.php?id=53256

  • Anonymous
    June 08, 2009
    PingBack from http://cellulitecreamsite.info/story.php?id=410

  • Anonymous
    June 08, 2009
    PingBack from http://quickdietsite.info/story.php?id=342