About dynamic Updates
As we develop workflows, we design our workflows in the Workflow Designer by dragging activities, setting properties, and so on, and we hope that the workflow that we defined at design time is unchanged at runtime. But in practice we often need to change the structure of the workflow at runtime, for example, we have defined a process in which we need to add a process point at the end, and this time we need to use dynamic update to reality. In WF we can also add deletion activities to the running workflow instance, modify activities, rule conditions, and so on. When dynamic updates are applied to a workflow instance, only the current instance of the workflow is affected. The rest and future are unaffected, and the original workflow definition is still used.
Dynamic updates are not appropriate for the overall change, because this causes the workflow to differ greatly from the original design principles. In such cases, you should design a new workflow instead of making changes to the running instance. Dynamic updates do not have to recompile and restart the workflow.
When to update dynamically
We can dynamically update the running workflow instance from inside and outside the workflow's execution thread. Internally, we can use codeactivity, custom activities, and so on, as workflows run on a single thread, so we don't have other activities executing when we perform dynamic updates. Externally, we have strict rules for implementing dynamic updates, which can be dynamically updated in the host program in the following states:
1. Workflow instance creation completed, but no start.
2. The workflow instance is suspended and is not recovered.
3. The workflow instance is idle.
We can complete the action update in the WorkflowRuntime workflowcreated,workflowsuspened,workflowidled event. The Workflowcreated event is raised after the Workflowruntime.createworkflow method call, and using suspendactivity can cause the work to be transferred to a pending state, raising the Workflowsuspened event. When you use DelayActivity or handleexternaleventactivity, the workflow enters the idle state, raising the Workflowidled event.
General Steps for dynamic updates
We use the following steps to dynamically update:
1. All proposed changes to the Run-time workflow instance must be made using the WorkflowChanges object. First we want to create an instance of the class that needs to pass the root activity of the workflow instance that was changed. If you are using the internal implementation Dynamic Update method, you can pass the This keyword directly. If you are in an external hosting program, you need to use the WorkflowInstance Getworkflowdefinition method to get the root activity of the workflow instance.
After the 2.WorkflowChanges object is created. The Transientworkflow property of the object returns the cloned version of the workflow instance, we make changes to the cloned version and then apply the changes to the running workflow instance.
3. We need to find the parent activity that you want to add or remove activities, you can use the CompositeActivity activities property or use the Getactivitybyname method to determine the parent activity, Then use the Add or Insert method to add or insert new activities. Remove the activity using the Remove method.
4. Use the WorkflowChanges Validate method to verify that the ValidationError object collection is returned if there are errors.
5. Verification can be updated after the adoption, if the external implementation of the action update needs to call the WorkflowInstance object's Applywrokflowchange method, the internal words will call the current object's Applyworkflowchanges method.
Prevent dynamic updates
The order and state machine workflows all have a dynamicupdatecondition attribute, and if you do not set the property workflow to always allow dynamic updates, when you set the attribute, you will calculate when you call the Applyworkflowchanges method. If true, dynamic updates are allowed, or an exception is thrown.
Dynamic Update Instance
Below we use in the workflow internal and external two ways to illustrate, first of all, we set up a sequential Workflow console program, workflow design the following figure:
The workflow code is as follows:
public sealed partial class CaryDynamicUpdateWorkflow: SequentialWorkflowActivity
{
public CaryDynamicUpdateWorkflow()
{
InitializeComponent();
}
private void beforeSequence_ExecuteCode(object sender, EventArgs e)
{
Console.WriteLine("beforeSequence执行了");
}
private void afterSequence_ExecuteCode(object sender, EventArgs e)
{
Console.WriteLine("afterSequence执行了");
}
private void IsUpdate(object sender, ConditionalEventArgs e)
{
e.Result = true;
}
}
We will add a custom activity printactivity to the Sequenceactivitycontainer in the workflow at run time, which simply prints a statement to the console with the following code:
public partial class PrintActivity : System.Workflow.ComponentModel.Activity
{
public PrintActivity()
{
InitializeComponent();
}
protected override ActivityExecutionStatus Execute (ActivityExecutionContext executionContext)
{
Console.WriteLine("自定义 Print活动");
return base.Execute(executionContext);
}
}