Updating instances using an update map in workflow 4.5

One of the really important new features in Windows Workflow Foundation 4.5 is the capability to version workflows and workflow instances. You get to choose what you want to do, either keep running existing instances with their original workflow definition or upgrade them to the latest workflow definition.


What should you do, upgrade exiting instances or run multiple definitions side by side?

Both the upgrade to latest and keep running with the original definition make sense in different scenarios. If you find a bug in your workflow definition the update scenario is probably what you are looking for. However if your business contract conditions change it makes sense to keep the older workflow instances with the original workflow definition and start new new workflows with the new definition. Both make sense, it’s just a matter of the requirements.

In this blog post I am going to explain how to do an upgrade of an existing workflow instance. In a future blog post I will go into side by side execution.

The basic steps

When upgrading a workflow instance we are always concerned with the following basic steps”

  1. Create your initial workflow definition.
  2. Start one or more instances using the this workflow definition.
  3. Prepare the original workflow definition for update.
  4. Make some changes to the workflow definition.
  5. Create an update map between the original workflow definition and the new one.
  6. Update exiting workflow instances to reflect the new workflow definition.

Create your initial workflow definition

This is the simple step as anyone that has been using Windows Workflow Foundation 4 has already been doing this. For this example I am using a real simple workflow that prints the version number it was started with and the current version.


One thing that is new here is associating a version with this workflow. When I create an instance of the WorkflowApplication I am using a WorkflowIdentity with a version of 1.0.

 1: private static WorkflowApplication CreateWorkflowApplication()

 2: {

 3:     var identity = new WorkflowIdentity

 4:     {

 5:         Version = new Version(1, 0)

 6:     };


 8:     var workflow = new TheWorkflow();

 9:     var app = new WorkflowApplication(workflow, identity);

 10:     app.InstanceStore = CreateSqlWorkflowInstanceStore();

 11:     app.PersistableIdle = e => PersistableIdleAction.Persist;

 12:     app.OnUnhandledException = e =>

 13:     {

 14:         Console.WriteLine(e.UnhandledException.Message);

 15:         return UnhandledExceptionAction.Abort;

 16:     };


 18:     return app;

 19: }

Start one or more instances using the this workflow definition

Again no big deal here, just run the workflow application.

 1: private static void StartNewWorkflow()

 2: {

 3:     WorkflowApplication app = CreateWorkflowApplication();

 4:     app.Run();

 5: }


Prepare the original workflow definition for update

In this step we prepare the workflow definition, the XAML file, for update using the DynamicUpdateServices.PrepareForUpdate() on an ActivityBuilder. This step adds a copy of the workflow definition in a DynamicUpdateInfo.OriginalActivityBuilder element so we can see the differences later when we are done. Right now we can use the workflow to run a workflow and everything would appear unchanged.


 1: private static void PrepareWorkflowForUpdate()

 2: {

 3:     ActivityBuilder builder = LoadWorkflowDefinition();

 4:     DynamicUpdateServices.PrepareForUpdate(builder);


 6:     SaveWorkflowDefinition(builder);

 7: }


 9: private static ActivityBuilder LoadWorkflowDefinition()

 10: {

 11:     ActivityBuilder builder;

 12:     using (var xamlReader = new XamlXmlReader(FileName))

 13:     {

 14:         var builderReader = ActivityXamlServices.CreateBuilderReader(xamlReader);

 15:         builder = (ActivityBuilder)XamlServices.Load(builderReader);

 16:     }

 17:     return builder;

 18: }


 20: private static void SaveWorkflowDefinition(ActivityBuilder builder)

 21: {

 22:     using (var writer = File.CreateText(FileName))

 23:     {

 24:         var xmlWriter = new XamlXmlWriter(writer, new XamlSchemaContext());

 25:         using (var xamlWriter = ActivityXamlServices.CreateBuilderWriter(xmlWriter))

 26:         {

 27:             XamlServices.Save(xamlWriter, builder);

 28:         }

 29:     }

 30: }

Make some changes to the workflow definition

In the workflow I am going to make a small change to reflect that it is workflow definition is version 1.1 and in the code I am going to use the same version 1.1.


If I try to resume the previously saved workflow definition this results in an VersionMismatchException.

Unhandled Exception: System.Activities.VersionMismatchException: The WorkflowIdentity (‘; Version=1.0’) of the loaded instance does not match the WorkflowIdentity (‘; Version=1.1’) of the provided workflow definition. The instance can be loaded using a different definition, or updated using Dynamic Update.


Create an update map between the original workflow definition and the new one

In order to upgrade the saved workflow instance we first need to create an update map. In this step we use the DynamicUpdateServices.CreateUpdateMap() function to create a map of the changes made since DynamicUpdateServices.PrepareForUpdate() was called. There is no way to create an update map based on anything else then the internal DynamicUpdateInfo. This means if you forgot to call DynamicUpdateServices.PrepareForUpdate() and save the workflow but instead just started making changes you are going to experience some problems. My first expectation was I could create an update map by comparing and older version of the workflow, for example from the TFS history, but that just isn’t possible using DynamicUpdateServices.CreateUpdateMap(). One solution here might be to use DynamicUpdateInfo.SetOriginalActivityBuilder().

Another slightly surprising thing is there is no native save functionality for a DynamicUpdateMap. In this case I am using a DataContractSerializer to save the update map in a way I can load it again.

 1: private static void CreateWorkflowUpdateMap()

 2: {

 3:     ActivityBuilder builder = LoadWorkflowDefinition();

 4:     DynamicUpdateMap updateMap = DynamicUpdateServices.CreateUpdateMap(builder);


 6:     SaveUpdateMap(updateMap);

 7: }


 9: private static void SaveUpdateMap(DynamicUpdateMap updateMap)

 10: {

 11:     var file


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s