c# - C# 中的简单状态机示例?

标签 c# state-machine

更新:

再次感谢您提供的示例,它们非常有帮助,对于以下内容,我不是说 拿走他们的任何东西。

就我对它们和状态机的理解,目前给出的例子难道不是我们通常理解的状态机的一半吗?
从某种意义上说,示例确实会改变状态,但这只是通过改变变量的值(并允许在不同状态下进行不同的值改变)来表示,而通常情况下,状态机也应该改变它的行为,而行为不(仅)在允许变量根据状态更改不同值的意义上,但在允许针对不同状态执行不同方法的意义上。

还是我对状态机及其常见用途有误解?


原始问题:

我发现了关于 state machines & iterator blocks in c# 的讨论以及为 C# 创建状态机等的工具,所以我发现了很多抽象的东西,但作为菜鸟,所有这些都有点令人困惑。

因此,如果有人可以提供一个 C# 源代码示例,它实现了一个可能具有 3,4 个状态的简单状态机,只是为了了解它的要点,那就太好了。

最佳答案

让我们从这个简单的状态图开始:

simple state machine diagram

我们有:

  • 4 种状态(不活动、事件、暂停和退出)
  • 5 种状态转换(开始命令、结束命令、暂停命令、恢复命令、退出命令)。

您可以通过多种方式将其转换为 C#,例如对当前状态和命令执行 switch 语句,或在转换表中查找转换。对于这个简单的状态机,我更喜欢转换表,它很容易用 Dictionary 表示:

using System;
using System.Collections.Generic;

namespace Juliet
{
    public enum ProcessState
    {
        Inactive,
        Active,
        Paused,
        Terminated
    }

    public enum Command
    {
        Begin,
        End,
        Pause,
        Resume,
        Exit
    }

    public class Process
    {
        class StateTransition
        {
            readonly ProcessState CurrentState;
            readonly Command Command;

            public StateTransition(ProcessState currentState, Command command)
            {
                CurrentState = currentState;
                Command = command;
            }

            public override int GetHashCode()
            {
                return 17 + 31 * CurrentState.GetHashCode() + 31 * Command.GetHashCode();
            }

            public override bool Equals(object obj)
            {
                StateTransition other = obj as StateTransition;
                return other != null && this.CurrentState == other.CurrentState && this.Command == other.Command;
            }
        }

        Dictionary<StateTransition, ProcessState> transitions;
        public ProcessState CurrentState { get; private set; }

        public Process()
        {
            CurrentState = ProcessState.Inactive;
            transitions = new Dictionary<StateTransition, ProcessState>
            {
                { new StateTransition(ProcessState.Inactive, Command.Exit), ProcessState.Terminated },
                { new StateTransition(ProcessState.Inactive, Command.Begin), ProcessState.Active },
                { new StateTransition(ProcessState.Active, Command.End), ProcessState.Inactive },
                { new StateTransition(ProcessState.Active, Command.Pause), ProcessState.Paused },
                { new StateTransition(ProcessState.Paused, Command.End), ProcessState.Inactive },
                { new StateTransition(ProcessState.Paused, Command.Resume), ProcessState.Active }
            };
        }

        public ProcessState GetNext(Command command)
        {
            StateTransition transition = new StateTransition(CurrentState, command);
            ProcessState nextState;
            if (!transitions.TryGetValue(transition, out nextState))
                throw new Exception("Invalid transition: " + CurrentState + " -> " + command);
            return nextState;
        }

        public ProcessState MoveNext(Command command)
        {
            CurrentState = GetNext(command);
            return CurrentState;
        }
    }


    public class Program
    {
        static void Main(string[] args)
        {
            Process p = new Process();
            Console.WriteLine("Current State = " + p.CurrentState);
            Console.WriteLine("Command.Begin: Current State = " + p.MoveNext(Command.Begin));
            Console.WriteLine("Command.Pause: Current State = " + p.MoveNext(Command.Pause));
            Console.WriteLine("Command.End: Current State = " + p.MoveNext(Command.End));
            Console.WriteLine("Command.Exit: Current State = " + p.MoveNext(Command.Exit));
            Console.ReadLine();
        }
    }
}

根据个人喜好,我喜欢用 GetNext 函数设计我的状态机以返回下一个状态 deterministically , 和一个 MoveNext 函数来改变状态机。

关于c# - C# 中的简单状态机示例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5923767/

相关文章:

c# - 使用 C# 阻止 Windows 7 的 Internet 连接

c# - 从网页预填充网页

c# - 主页错误,命名空间已存在

rest - 用什么PATCH或POST?

复杂的状态转换 : best practices

C# 一遍又一遍地循环一个过程,直到用户按下一个键

c# - INotifyDataErrorInfo 和绑定(bind)异常

java - 恢复 Spring State Machine 实例时的推荐方法

java - 有什么工具可以帮助用户设计要由我的应用程序使用的状态机?

c - 大型与嵌套状态机