WF4 Advanced State Machine Stuff

So you want to know how the state machine really works?

Take a look at the WF4 State Machine Explorer.  This sample is designed to show you how StateMachine works with activities.

image

There are three transitions from State1.

  1. To State 2 which is triggered by a bookmark named “State2”
  2. To State 3 which is triggered by a bookmark named “State3”
  3. A Countdown transition which will count down from 10 seconds until it reaches zero at which point the condition is enabled and the workflow ends.

Now this can get a bit confusing but I think it is important to understand how the State Machine activity schedules child activities. 

Start to First Idle

  1. StateMachine will schedule the first state (State 1) – note you cannot have more than one first state
  2. State1 will execute and Tracking will receive a StateMachineStateRecord with the CurrentState set to State1
  3. State1 will schedule the Entry actions (if any)
  4. The Entry actions will execute
  5. When the Entry actions are complete, State1 will schedule the Trigger actions for each trigger in the order they are listed in the XAML (see <State.Transitions>)
  6. The trigger actions will execute in the order they were scheduled

Watch Out

In WF 3.5 the State Machine required that triggering activities implement a certain interface.  In WF4 there is no such requirement.  Any activity (or activities) can appear in a trigger.  This brings up some interesting possibilities.

Whenever there is more than one trigger, you have a race.  Each trigger is racing to complete and the first one which completes successfully and passes the condition wins.  The other triggers will be canceled when this happens.

What happens if a trigger has no activities?

This is known as a null trigger, trigger-less transition or unconditional transition.  It will immediately transition and cancel the others.  The State Machine designer will validate that your activity has only one of these.

What happens if a trigger has activities that don’ t cause the workflow to become idle?

The activities will run and then the condition will be evaluated.  If the condition fails, the activity will be scheduled to run again (and again) until the condition evaluates true or one of the other transitions completes and passes the condition test.  The transition that wins will cause the others to be canceled.

What if I want a transition that is conditional?

The WF4 State Machine design assume that the condition will be set by something that occurs in the trigger.  It will always run the activities in the trigger and then evaluate the condition.  If you don’t want to run the activities in the trigger you have to use control flow (like an If activity) to avoid this.

What happens if I resume a bookmark and one of the other triggers fires before the desired trigger can evaluate the condition?

If you create a trigger that is very busy (running several times a second) there is a good chance that none of your other triggers will ever get a chance to complete and cancel the busy trigger.

What happens if a transition does not pass the condition?

Transitions can have a condition associated with them.  If the Boolean expression evaluates to false, the trigger action will be scheduled again.  None of the other transitions will be affected.

How do you figure all this stuff out?

Tracking is your friend.  I’m in the process of moving my tracking extensions into Microsoft.Activities but right now they are in Microsoft.Activities.UnitTesting.  In the sample code you will notice that I have a simple class called Tracker

    1: internal class Tracker : TrackingParticipant
    2: {
    3:     protected override void Track(TrackingRecord record, TimeSpan timeout)
    4:     {
    5:         // Using extension method to get a human readable trace
    6:         record.Trace();
    7:     }
    8: }

Now all I need to do is to add an instance of this class to the Extensions collection

    1: var workflowDefinition = new AStateMachine() {EnableCountdown = EnableCountdown};
    2: var host = new WorkflowApplication(workflowDefinition) { Completed = (e) => completed = true };
    3:  
    4: // Setup the Tracking to output in the debug window
    5: host.Extensions.Add(new Tracker());

Now when I run my app I see tracking information in the VS Debug Output

 WorkflowInstance <AStateMachine> is <Started> at 05:06:21.1862
 Activity <null> is scheduled child activity <AStateMachine> at 05:06:21.1882
 Activity <AStateMachine> state is Executing at 05:06:21.1892
 {
     Arguments
         EnableCountdown: False
 }
 Activity <AStateMachine> is scheduled child activity <StateMachine> at 05:06:21.2052

Comments

  • Anonymous
    May 04, 2011
    The comment has been removed

  • Anonymous
    May 04, 2011
    Great - if you like the sample, please be sure to give it a rating on MSDN Code Gallery.

  • Anonymous
    May 06, 2011
    Hi, Ron: I downloaded your Statemachine_HOL, I am curious about the persistence of statemachine, hence, I tried to add sqlworkflowpersistenceService to worklfowhost, however, I was not able to do so becuase the System.Workflow.Runtime is not included in the .netframeframework 4 client profile update 1. could you please shed some light on the persistence side of statemachine?

  • Anonymous
    May 06, 2011
    System.Workflow.Runtime is WF3. You need a difference persistence model see SQL Workflow Instance Store msdn.microsoft.com/.../ee383994.aspx

  • Anonymous
    May 09, 2011
    Thanks Ron, I got it working. Thanks for your prompt help.

  • Anonymous
    May 09, 2011
    Hi, Ron: Statemachine workflow can be put behind workflow service like sequential workflow and flowchart, right?

  • Anonymous
    May 10, 2011
    Yes - you can implement a Workflow Service with a State Machine.  Just put the Send/Receive activities in a trigger

  • Anonymous
    May 10, 2011
    Thank you so much for your help, it is very nice to know that you are there to help us(user)!

  • Anonymous
    May 10, 2011
    Hi, Ron: Could you please tell me what kind of role meta data played in WF? I am trying to get a handle on WF and I definite will have a lot of questions, is it possible to contact you directly for questions? Thanks a lot.

  • Anonymous
    May 10, 2011
    Hi, Ron: I have a question about triggers of statemachine, it looks to me that workflow runtime does not wait for the triggers to from outside, my first state has two triggers, each has a code activity as trigger, for some reason, the workflow went straight to one of trigger without waiting for my code to tell it to run that trigger. did I do anything wrong? thanks

  • Anonymous
    May 10, 2011
    You should take a look at the Introduction to State Machine HOL - it will help you understand how it works. code.msdn.microsoft.com/Windows-Workflow-b4b808a8 Your activities have to wait for something (typically with a bookmark)

  • Anonymous
    May 10, 2011
    Feel free to send me a question using the Email Blog Author link (above)