Hello State Machine fans!  There have now been several eras of support for state machines in WF4 and WF3, and I think it would be good for a retrospective, part stocktake, part promo and making sure everyone is up-to-date (+reminder of CTP license terms), and so on. It’s targeted less at solving specific problems, more at casual searchers and general knowledge (I mean trivia). Sound like fun? If so, read on...

 

The first era: WF3

WF3 was of the first WF version to support State Machine. It implemented state machines using the StateMachineWorkflowActivity class. In general it has the same basic StateMachine features that we expect of any state machine, which is states (implemented by StateActivity-s), and transitions (implemented in ways I consider complicated).

There are a  few things about the WF3 StateMachine programming model which are quite interesting in retrospect, especially with regards to backwards compatibility of expectations:

  • In WF3 StateActivity is an Activity! (In WF4, State is not an Activity)
  • In WF3 StateMachineWorkflowActivity and StateActivity are both subclassable! (In WF4, StateMachine and State are sealed)
  • For modelling events and state transitions WF3 appears to rely on a type called EventDrivenActivity which I don’t yet understand… but it appears to be an approximate analogue to a NativeActivity with CanInduceIdle = true, i.e. one that can create bookmarks [can you tell I’m learning WF3 as I go along? Smile with tongue out]
  • WF3 allowed querying the State Machine’s current state, i.e. ‘GetState()’
  • WF3 allowed ‘goto State’ functionality in the form of ‘SetState()’

[Also from what I have briefly gleaned, WF3 also sounds like it allowed some nested state scenarios? I’m not really clear on what these are like maybe someone can point me at an example.]

 

The second era: WF4 (from Beta to RTM)

State Machine was planned as one of the features of WF4 from early days, but midway through the project StateMachine got cut. Even at Microsoft, or perhaps especially at Microsoft, feature cuts happen very frequently during a large development project – the reason being time pressure. Sometimes these cuts are hard to make, even painful, especially if we know it will cause customer discontent. But cuts have to be made regardless, because sometimes there are just too many good ideas to implement them all.

So the release of WF4, and all of the Beta releases, came full of State Machine migration guidance [ref: Migration Guidance for the WF Developer] (which tried to sell people on the idea of using Flowchart/Pick as substitutes), and feedback from the forums on that guidance, including some choice sound bites:

  • “You just don't do Business Process Modelling without state machines. Also, state machines are easiest way to program reactive systems by a country mile.”
  • “My vote is to definitely have support for StateMachine in WF4. The stopwatch example in the guidance document should be enough to persuade anyone of that.”
  • ”To say we're bummed is an understatement.”

Obviously there’s not much to say about WF State Machine itself in this era.

The third era: State Machine CTP release on CodePlex

April 2010 saw the CTP release of a State Machine installable download with full source code on wf.codeplex.com.

It’s not still there to download, if you missed out on it you may never get to actually use it, however you can piece together a picture from blog and forum posts, endpoint.tv/channel 9, and and the wf.codeplex source control revision history. State Machine is finally represented by a ‘StateMachine’ class, states are represented by ‘State’ objects, and transitions are ‘Transition’ objects which are properties of the state they transition from.

Blurry giant screen capture of Channel 9

One of the really nice features that the State Machine CTP had you can see in this diagram is nested states. Unfortunately nested states is not in the succeeding official release of State Machine. This causes yet another round of customer compatibility/expectation issues for people who try out the CTP and later want to upgrade from the CTP to the official State Machine release. Unfortunately due to one of the license terms of the CTP, there is no choice but to upgrade:

“(F) You are not obligated to exercise the Additional Use Rights. But if you do, the Additional Use Rights are subject to the following additional terms and conditions:
• Update - If Licensor releases a final, commercial version of the software (or any of its component) for which you are exercising Additional Use Rights, you will incorporate such final, commercial version of the software (or such component) within a commercially reasonable period after Licensor’s commercial release.
• Indemnification - You agree to indemnify, hold harmless, and defend Licensor from and against any claims, allegations, lawsuits, losses and costs (including attorneys’ fees), that arise or result from your exercise of Additional Use Rights.
• Platform Limitation - The Additional Use Rights extend only to the software or permitted derivative works that you create that run on a Microsoft Windows operating system product.”

CodePlex Discussions of the era:

Workflow event’ / ‘How can I use WCF to trigger a state machine workflow?’ / ‘Statemachine: Shared trigger‘ – customers getting used to the new, simpler WF4 way of designing state transitions

adding transitions while running’ – WF3 customers who are used to GetState/SetState finding out this concept doesn’t exist yet in WF4

and post-era transition:

Composite state’ – What happened to nested states?

 

The fourth era: State Machine in Platform Update 1

Finally we reach the present day and State Machine at last has an official release in the .NET Framework – just it is an opt-in update instead of a mainstream .NET release. To celebrate, and to invalidate all the old information about WF4 not having State Machine, there are announcements galore on blogs and forums to try and make sure everyone has the most up-to-date information.

“State Machine workflows are available in the .NET 4 Platform Update 1: http://blogs.msdn.com/b/endpoint/archive/2011/04/18/microsoft-net-framework-4-platform-update-1.aspx

“WF4 State Machine Codeplex project has been retired. With the release of WF4 State Machine in .NET Framework Platform Update 1 (KB2495638), we decided to retire the WF4 State Machine Codeplex project. The feedbacks you provided to this project helped us to shape up the version in the official release. Thank you!”

Ron Jacobs released a hands-on-lab for State Machine (which I also linked at the top). An updated version of the WF Migration toolkit was released for migrating WF3 declarative workflows.

And so now that we have reached the present…

is everybody happy? Well…

There are still a few features missing if you compare with either WF3 or the CTP. Especially Get/SetState, and nested states. Isaac Yuen, PM from the designer team made a little comment about the nested states (in this thread)

In Workflow 4, we decided to simplify the model, such that there is only one level of states in the StateMachine. While that should make reading the StateMachine a lot easier, in terms of "nested" states, this does mean that - "Yes", it requires one explicit transition from each state to the final state. If multiple states are listening to the same external message, then it also means that you would need to copy/paste the "Receive" activity in the trigger of the transitions.

Yes - we are aware of that and we are now working on a way to hopeful ease the usability of this "transition duplication"

So the good news is that there are definitely some State Machine improvements still to come, and hopefully I will need to update this post once another update is released. (To forestall questions, I officially have no idea when this will happen.)

Aside from those functional issues, the State Machine like Flowchart, lacks extensibility points in the designer side, which was one of the nice side effects of 3.x state machine’s implementation.

There are also a few more minor problems customer have had while getting started which are kind of interesting.

The first (which Josh reminded me of below) is that the release vehicle is a Platform Update. With the way that VS project platform targetting works, targetting Platform Update 1 at the same time as another out-of-band .NET releases, like Entity Framework 4.1 (Magic Unicorn Edition**) is not, as far as I know, feasible. Additionally, tools outside of Visual Studio, like Expression Blend, apparently have some problems

The second is that State Machine apparently just doesn’t show up in the toolbox some times? I’m still not actually sure if all the suggestions in these threads are solving people’s problems. If you’ve tried everything and you’re still having trouble drop me a line.

Epilog – the Era I missed!

Alert reader Josh wrote in* by email to add an interesting note:

You forgot the 'bell epoch' era - NET 3.51 Workflow Services - where we had an application level protocol - the state machine events mapped to a WCF service contract operations, and you had a convention for legal state transfers driven by WCF operations supported by that state. certain operations were only supported in certain states. Other gripes: 1) 4.0.1 out of band target framework introduces dependencies that are not supported by Expression Blend, and that are incompatible with that other out of band target framework release for the Entity Framework. 2) As State class does not derive from Activity, the WorkflowDesigner WPF control cannot highlight the current state - had to hack with VisualTreeHelper 3) StateMachineActivity lacks Get/Set current state - requiring alot of custom infrastructure

And obviously all my Era numbering is wrong, d’oh. I’m feeling a little happier about the article after this and some other minor fixes but let me know if it still sucks.

Footnotes:
*Dave Barry is awesome. Smile
**I am not making this up!