State Machine Workflow with WinWF

Welcome to this installment of the .NET Nuts & Bolts column. This article will walk through building a state machine workflow, which is one of the several workflow types supported by the Microsoft .NET Framework 3.0 and Visual Studio 2005.

Necessary Components and Setup

You will need to have the following components to build the examples contained within this article. I personally downloaded them and set up a .NET Framework 3.0 Virtual PC environment. I’ve found this to be a good practice for trying out new things and for preserving various environments. It is especially handy when you have a particular environment that you need to support every so often that is outside your normal development.

State Machine Workflow

In my article Get Ready for Windows Workflow Foundation, the focus was on sequential workflow, which involves a prescribed processing order that relates closely to a top-down sequential flowchart model. In comparison, a state machine workflow is more flexible and you have more control and visibility in to the state. Whereas a sequential workflow involves a set of activities that are set up to occur in a pre-defined sequence, a state machine workflow models the possible states for a particular entity and specifies events. A set of events can be received for any given state. When events occur, an action is performed; at the end of this action, a state transition may or may not be made. Steps in the workflow can be skipped and/or jump to any step in the workflow. This type of activity is ideal when the exact sequence of events is not well known in advance.

Although a state machine is different in behavior than a sequential workflow, it can use the same activities as a sequential workflow. Thus, actions taken within any particular transition of state can contain sequential activities and other logic, which can allow for a best of both workflow styles to better match processses. There is a base activity library that contains some activities for state machine workflow. They include:

  • EventDriven: Defines a transition that is executed when a specific event is received while in a particular state. The transition contains one or more activities to be executed when the specific event is received.
  • SetState: Changes the state of the state machine from one state to another.
  • State: Represents a particular state in the state machine.
  • StateInitialization: Defines one or more activities that that are executed whenever an assigned state is entered.

Building a State Machine Workflow

A state machine workflow is commonly used in scenarios such as the following:

  • Human interaction with a process where there are delays in processing or different flow of activities
  • Ad hoc transitions within a process as opposed to sequential flow
  • Workflow is driven by external events or influencing entities

State machine workflows that very commonly represent business processes as entire processes rarely flow sequentially from beginning to end. Fulfillment of orders through an e-commerce system, new account creation process, and employee on boarding are all example processes that may fit well into a state machine model. For this article, my colleague Rachel has come up with a sample involving choosing your favorite color. This sample will allow you to keep things relatively simple for the purposes of this article. The states for this example are starting, selecting red as your favorite color, selecting blue as your favorite color, and ending the workflow.

Use the following outlined steps to create a state machine workflow within Visual Studio 2005. There are a number of steps to describe as you walk through the example. As with any set of detailed instructions, you may have to read through them carefully a few times to ensure you catch all of the parts.

  • Create a new project: For my example, I’m using C#, Workflow, State Machine Workflow Console Application as the project type.
  • When you create the workflow project, it will use the workflow definition and code in the same file by default. I deleted it and added a new item, State Machine Workflow (with code separation),. and named it FavColor.xoml. I prefer the code separation for maintainability purposes.
  • By default, the state machine workflow will have an StateInitialization activity in the designer, which I deleted for this example. From the Visual Studio Toolbox, you should find a Windows Workflow tab if you have your environment installed properly. Drag four state activities onto the designer. I named them stateActivityStart, stateActivityRed, stateActivityBlue, and stateActivityEnd.
  • Note: The designer for the state machine is freeform so you can locate states wherever you would like.

  • Click the background on the state workflow designer, right-click, and select properties. In the properties window for the state machine workflow, set the InitialStateName property to stateActivityStart. Set the CompletedStatename property to stateActivityEnd.
  • Drag an EventDriven activity from the Toolbox on to the top of the stateActivityStart state and name it something similar to eventDrivenActivityAskForColor.
  • Drag an EventDriven activity from the Toolbox on top of the stateActivityRed state in the designer and name it something similar to eventDrivenActivityRed.
  • Drag an EventDriven activity from the Toolbox on top of the stateActivityBlue state in the designer and name it something similar to eventDrivenActivityBlue.
  • The design canvas should now look similar to the following:
  • In the designer canvas, double-click on the eventDrivenActivityAskForColor activity in the stateActivityStart state. The first child activity of an EventDriven activity must implement IEventActivity and states generally handle events. To make this example as simple as possible, however, you will use the Delay activity as the first child of all EventDriven activities with the delay property set to 1 second. Add a Delay activity of this description to the eventDrivenActivityAskForColor activity.
  • When you set the ExecuteCode property, Visual Studio will bring you to the handler in the code behind. Add the following code to the handler:
  • private void codeActivityAskFavColor_Execute(object sender,
                                                 EventArgs e)
    {
       Console.Write("Enter 1 for red and 2 for blue:  ");
       string answer = Console.ReadLine();
       while (answer != "1" && answer != "2")
       {
          Console.Write("Please enter a 1 or 2:  ");
          answer = Console.ReadLine();
       }
    
       FavColor = answer;
    }
    
  • You also will need to add the following field and property to the workflow object:
  • private string favColor = "";
    public string FavColor
    {
       get { return favColor; }
       set { favColor = value; }
    }
    
  • Switch back to the designer view and add an IfElse activity below the code activity in the designer canvas.
  • Name the IfElse activity’s left branch ifElseBranchActivityRed. Set the Condition property to “Declarative Rule Condition.” Expand the Condition property and click on the ellipsis. Add a condition and set its body to: this.FavColor.Equals(“1”). Rename it to “ConditionRed”. Add a second condition and set its body to: this.FavColor.Equals(“2”). Rename it to “ConditionBlue”. Select “ConditionRed” and click OK. This is a simple demonstration of allowing you to make a logic decision based on state.
  • Name the IfElse activity’s right branch ifElseBranchActivityBlue. Set the Condition property to “Declarative Rule Condition.” Expand the Condition property and click on the ellipsis. Choose “ConditionBlue” and click OK.
  • Add a SetState activity to both the left and right branches and name them setStateActivityRed and setStateActivityBlue respectively. Set their TargetStateName properties to stateActivityRed and stateActivityBlue respectively.
  • The designer for stateActivityStart should now have the components similar to the following diagram:
  • Return to the designer canvas for the workflow. You will notice there are transition lines that now will appear from the starting state to the red and blue states. These lines are a result of the SetState activities and can be controlled through the designer.
  • Double-click on the eventDrivenActivityRed activity in the stateActivityRed state.
  • Add a delay event using similar steps to what you followed for the last delay event.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read