views:

92

answers:

0

I have a Windows Workflow Foundation (3.0) StateMachine workflow with about 20 states. I can successfully remove a simple state from it at runtime, but if the state is more complex (ie. it can transition into or from multiple states) I run into an error. Because properties can't be changed at runtime I have to remove activities and then add them back with the SetState target value changed so as to stop the workflow trying to transition into the state that I originally wanted removed.

For example, if the workflow states are A, B, and C, and A->B, A->C, and B->C, and I want to remove state B, then I have to update A to remove the SetState activity which sends it to the now removed B. AFAIK this can only be done by removing A, and adding it back with the SetState activity removed. So two states have been removed, with one added back. When I do this, and then call ApplyWorkflowChanges(workflowChanges) it throws and error saying "workflow changes already applied", whereas if I only remove one state it works fine.

The error is a System.InvalidOperationException and the text is "WorkflowChanges have already been applied. Create a new WorkflowChanges object to apply new changes or to re-apply previously failed changes."

Here is my code:

private void codeActivity1_ExecuteCode(object sender, EventArgs e)
{
    WorkflowChanges wfChanges = new WorkflowChanges(this);  // "this" is the StateMachine object
    StateActivity aaa = wfChanges.TransientWorkflow.Activities["ASMAgentAppointment"] as StateActivity;
    wfChanges.TransientWorkflow.Activities.Remove(aaa);

    StateActivity qfu = wfChanges.TransientWorkflow.Activities["QuoteFollowUp"] as StateActivity;
    int i = wfChanges.TransientWorkflow.Activities.IndexOf(qfu);
    wfChanges.TransientWorkflow.Activities.Remove(qfu);

    EventDrivenActivity oaaab = qfu.Activities["onASMAgentAppointmentBooked"] as EventDrivenActivity;
    qfu.Activities.Remove(oaaab);
    wfChanges.TransientWorkflow.Activities.Insert(i, qfu);

    this.ApplyWorkflowChanges(wfChanges);
}