Working with State Machines in the .NET Framework

In this article I will introduce the readers to the state machine model and also create a simple working state machine sample using the .NET framework in C# language.

What is a State Machine?

Any device that changes its state from one to another due to some actions are defined to be state machines. For example an ATM machine, traffic signal, remote control, the computer itself, etc. Most software applications also depend and operate based on the state. There are two types of state machines.

1. Finite state machine – A state machine holding a defined set of states and they work within that.

2. Infinite state machine – Here the states can be many and cannot be predefined.

Most common state machines are finite ones.

Composition of a State Machine

The following things collectively make an effective finite state machine.

State:

A defined set of states. At any point of time the state machine will be in any one of the defined states. For example Red, Green and Yellow in a traffic signal system.

State Transition:

A state machine changing its state from one to another is called State Transition. Usually there will be a state transition table built that will contain the state sequences and also metadata saying which event will cause which state transition.

Triggers:

Triggers are the points that induce the state transition in a state machine.

Events or Actions:

Actions are performed by the state machines when a particular state is attained and exited. There will be Entry and Exit actions for each state.

Guard Condition:

This is the piece of component that validates the transition and ensures that no invalid state changes are carried out.

State Machine Vs State Pattern

State pattern is one among the Gang of Four patterns. Most people have an impression that state machine and state pattern are different but the truth is state pattern is one way to implement a state machine. There are other ways available to build sophisticated state machines including all the components mentioned in the above section.

Traffic Signal State Machine Example

Let us create a simple state machine using a state pattern in .NET framework. The state machine that we are going to build is a Traffic Signaling system, which changes the signals within specific time intervals once the system is started.

Create a state interface named IState, which will be implemented by all the available states.

namespace FiniteStateMachine
{
    public interface ISignalState
    {
        void Enter(TrafficSystem system);
    }
}

Next let us create the states for the traffic signal. The states will be Red, Green and Yellow.

namespace FiniteStateMachine
{
    public class RedState : ISignalState
    {
        const int SIGNAL_TIME = 5000;
 
        public void Enter(TrafficSystem system)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("Entered Red.");
            Thread.Sleep(SIGNAL_TIME);
            system.NextTrafficSignal = new GreenState();
            system.ChangeSignal();
        }
    }
}
namespace FiniteStateMachine
{
    public class GreenState : ISignalState
    {
        const int SIGNAL_TIME = 10000;
 
        public void Enter(TrafficSystem system)
        {
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("Entered Green.");
            Thread.Sleep(SIGNAL_TIME);
            system.NextTrafficSignal = new YellowState();
            system.ChangeSignal();
        }
    }
}
namespace FiniteStateMachine
{
    public class YellowState : ISignalState
    {
        const int SIGNAL_TIME = 3000;
 
        public void Enter(TrafficSystem system)
        {
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("Entered Yellow.");
            Thread.Sleep(SIGNAL_TIME);
            system.NextTrafficSignal = new RedState();
            system.ChangeSignal();
        }
    }
}

Now comes the traffic system that holds an initial state, which is Green and then changes its context state periodically. It exposes a Start function, which is a handle for the clients to kick start the traffic system.

namespace FiniteStateMachine
{
    public class TrafficSystem
    {
        public ISignalState NextTrafficSignal { get; set; }
        public void Start()
        {
            NextTrafficSignal = new GreenState();
            NextTrafficSignal.Enter(this);
        }
 
        public void ChangeSignal()
        {
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine("###########Signal changed##########");
            NextTrafficSignal.Enter(this);
        }
    }
}

Now we are good to hook it up to the client, which is a console app Main function in our case.

    class Program
    {
        static void Main(string[] args)
        {
            TrafficSystem system = new TrafficSystem();
            system.Start();
 
            Console.ReadLine();
        }
    }
 

Run the application and you should see the signal changing behavior as shown in Fig 1.0.

Signal Changing Behavior
Fig 1.0: Signal Changing Behavior

It is not only about creating the state machine application but also can be extended into creating state machine frameworks that can be used by other applications. .NET framework has integrated the state machine framework in the form of Workflow foundation.

Happy reading!



Related Articles

Downloads

Comments

  • Not a great example

    Posted by Rob Herbert on 07/22/2014 06:24am

    I know you're just trying to give an example of how state machines work but this isn't a good one. Quite apart from anything else, that program will eventually crash with a stack overflow error because you've got the state objects calling the system object, which calls the state objects, and so on.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • On-demand Event Event Date: October 29, 2014 It's well understood how critical version control is for code. However, its importance to DevOps isn't always recognized. The 2014 DevOps Survey of Practice shows that one of the key predictors of DevOps success is putting all production environment artifacts into version control. In this webcast, Gene Kim discusses these survey findings and shares woeful tales of artifact management gone wrong! Gene also shares examples of how high-performing DevOps …

Most Popular Programming Stories

More for Developers

RSS Feeds