How to: Apply Workflow Changes to Workflows
The ability to make changes to a running workflow instance dynamically is consistent with typical human workflow scenarios. For example, an interview workflow that has four interviewers might be changed at run time to add a fifth step in response to new information that requires additional perspective on a candidate.
These workflow changes can be applied to a running workflow instance both from inside and outside the workflow's thread of execution. From the inside, changes are typically applied by using an activity's event handler, or directly into the execution logic of a custom activity. From the outside, you can use the Windows Workflow Foundation API in the host application to access the workflow and make the necessary changes. To ensure that workflow changes are applied correctly, the host should only apply them when the workflow instance is either suspended or guaranteed to be idle.
|Workflow changes are not permanent changes to a given workflow type and will not be propagated to future instances of that type.|
Authoring Within a Workflow
Windows Workflow Foundation provides the WorkflowChanges class to facilitate workflow changes within the workflow. Activities are added through the Add method of the composite activity that is to be the parent of the new added activity. Conversely, an activity can be removed through its parent composite activity Remove method. These changes are batched in the transient class.
When workflow changes are performed, the Validate method can be called. The Validate method performs semantic checks on the activity graph to ensure semantic correctness at run time before locking it in memory. You can then call the ApplyWorkflowChanges method from a WorkflowInstance object, passing a WorkflowChanges object as the parameter for any number of instances of the same workflow type. However, you can call the ApplyWorkflowChanges method only one time on an instance for a given transient class.
The following code example shows how you can use the WorkflowChanges class to add changes to a workflow instance.
InvokeWorkflowActivity invokeNewWorkflow = new InvokeWorkflowActivity(); WorkflowChanges changes = new WorkflowChanges(this); // // NewWorkflow type // Type type = typeof(Workflow1); invokeNewWorkflow.Name = "NewWorkflow"; invokeNewWorkflow.TargetWorkflow = type; // // Add NewWorkflow after delay. // DelayActivity delay = changes.TransientWorkflow.Activities["delay1"] as DelayActivity; delay.Parent.Activities.Add(invokeNewWorkflow); // // Apply transient changes to instance. // this.ApplyWorkflowChanges(changes);
Because multiple instances of a workflow share the same activity tree, when a dynamic change occurs, the activity tree is cloned to make the change, while the rest of the instances continue to share the original activity tree.
Authoring from the Host Environment
The WorkflowInstance class exposes the ApplyWorkflowChanges method to enable authoring dynamic changes from outside the workflow. Most of the time, this method is used by the hosting environment.
To apply a workflow change from the hosting environment to a running workflow instance, navigate to the instance in which workflow change is to be made and obtain its WorkflowInstance. The runtime creates a WorkflowInstance for each instantiation of a workflow. The host can obtain the WorkflowInstance of a workflow by saving the return parameter when CreateWorkflow is called.
After the WorkflowInstance object is obtained, create a WorkflowChanges object and use the various methods and properties of that object to apply a workflow change. When this occurs, the host is working with a copy of the WorkflowInstance. To apply the workflow change to the currently executing WorkflowInstance, call the ApplyWorkflowChanges method from the WorkflowInstance object.
For an example of dynamically updating a workflow from a host, see the Workflow Changes From Host.
Workflow Changes and Activity Properties
Setting properties on transient workflow activities works as follows:
For metadata properties, the values set on a transient workflow are effective on the running workflow, after the update is applied.
For instance properties, the values set on a transient workflow are lost, after the update is applied. The original running workflow values are preserved.