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.
There are three transitions from State1.
- To State 2 which is triggered by a bookmark named “State2”
- To State 3 which is triggered by a bookmark named “State3”
- 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
- StateMachine will schedule the first state (State 1) – note you cannot have more than one first state
- State1 will execute and Tracking will receive a StateMachineStateRecord with the CurrentState set to State1
- State1 will schedule the Entry actions (if any)
- The Entry actions will execute
- 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>)
- 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 removedAnonymous
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.aspxAnonymous
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 triggerAnonymous
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? thanksAnonymous
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)