C# 包含有限状态机吗?

问题描述 投票:0回答:9

我最近读到了

boost::statechart
库(有限状态机),我喜欢这个概念。

C#有类似的机制吗?或者可以使用特定的设计模式来实现吗?

c# .net design-patterns finite-automata fsm
9个回答
20
投票

.NET 4 Update 1 现在在以下类中支持它: 系统.活动.语句.状态机

这里有一个如何使用它的教程。 这是一个动手实验室


8
投票

Workflow Foundation (.NET 3.0) 具有状态机工作流程。 4.0 目前没有完全相同的东西,但是您绝对可以使用 4.0 创建状态机工作流程。


6
投票

我维护一个开源项目,它实现了(除其他外).NET 的通用有限状态机。 它建立在 QuickGraph 之上,因此您可以免费获得许多图形分析算法。

请参阅此页面,了解有关该项目的更多信息,特别是“Jolt.Automata:有限状态机”,了解有关该功能的更多信息。


5
投票

查看无状态 -> http://code.google.com/p/stateless/。 它是较重的 WWF 的轻量级替代品。

以下是该工具作者的几篇文章:

领域模型中的状态机

无状态中的参数化触发器和可重入状态


2
投票

最接近 FSM 的是 .NET 3.5 中的工作流,但是,工作流也不完全是 FSM。

使用 FSM 的强大之处在于,您可以在代码中显式地创建它们,从而减少产生错误的机会。此外,当然有些系统本质上就是 FSM,所以像这样编码更自然。


1
投票

Windows Workflow Foundation (WF) 是 3.0 和 3.5 中基类库的一部分,包括状态机工作流设计,用于管理应用程序的状态机。

他们为即将发布的 4.0 版本完全重写了工作流程,并且新的 WF 4.0 类本身不支持状态机,但所有 3.0/3.5 类在 4.0 下仍然完全受支持。


0
投票

是的,C# 有迭代器块,它们是编译器生成的状态机。

如果您希望实现自己的状态机,您可以创建

IEnumerable<T>
IEnumerator<T>
接口的自定义实现。

这两种方法都强调了 .NET 框架对迭代器模式的实现。


0
投票

如果您正在寻找一个简单的状态机,我们刚刚发布了一个开源 .NET 项目,它具有流畅的 API 以及用于构建状态机工作流程的设计器。这是该项目的链接:https://github.com/Kingfish219/FlowCiao 这是 Nuget:https://www.nuget.org/packages/FlowCiao


-1
投票

此存储库中的其他替代方案https://github.com/lingkodsoft/StateBliss 使用流畅的语法,支持触发器。

    public class BasicTests
    {
        [Fact]
        public void Tests()
        {
            // Arrange
            StateMachineManager.Register(new [] { typeof(BasicTests).Assembly }); //Register at bootstrap of your application, i.e. Startup
            var currentState = AuthenticationState.Unauthenticated;
            var nextState = AuthenticationState.Authenticated;
            var data = new Dictionary<string, object>();

            // Act
            var changeInfo = StateMachineManager.Trigger(currentState, nextState, data);

            // Assert
            Assert.True(changeInfo.StateChangedSucceeded);
            Assert.Equal("ChangingHandler1", changeInfo.Data["key1"]);
            Assert.Equal("ChangingHandler2", changeInfo.Data["key2"]);
        }

        //this class gets regitered automatically by calling StateMachineManager.Register
        public class AuthenticationStateDefinition : StateDefinition<AuthenticationState>
        {
            public override void Define(IStateFromBuilder<AuthenticationState> builder)
            {
                builder.From(AuthenticationState.Unauthenticated).To(AuthenticationState.Authenticated)
                    .Changing(this, a => a.ChangingHandler1)
                    .Changed(this, a => a.ChangedHandler1);

                builder.OnEntering(AuthenticationState.Authenticated, this, a => a.OnEnteringHandler1);
                builder.OnEntered(AuthenticationState.Authenticated, this, a => a.OnEnteredHandler1);

                builder.OnExiting(AuthenticationState.Unauthenticated, this, a => a.OnExitingHandler1);
                builder.OnExited(AuthenticationState.Authenticated, this, a => a.OnExitedHandler1);

                builder.OnEditing(AuthenticationState.Authenticated, this, a => a.OnEditingHandler1);
                builder.OnEdited(AuthenticationState.Authenticated, this, a => a.OnEditedHandler1);

                builder.ThrowExceptionWhenDiscontinued = true;
            }

            private void ChangingHandler1(StateChangeGuardInfo<AuthenticationState> changeinfo)
            {
                var data = changeinfo.DataAs<Dictionary<string, object>>();
                data["key1"] = "ChangingHandler1";
            }

            private void OnEnteringHandler1(StateChangeGuardInfo<AuthenticationState> changeinfo)
            {
                // changeinfo.Continue = false; //this will prevent changing the state
            }

            private void OnEditedHandler1(StateChangeInfo<AuthenticationState> changeinfo)
            {                
            }

            private void OnExitedHandler1(StateChangeInfo<AuthenticationState> changeinfo)
            {                
            }

            private void OnEnteredHandler1(StateChangeInfo<AuthenticationState> changeinfo)
            {                
            }

            private void OnEditingHandler1(StateChangeGuardInfo<AuthenticationState> changeinfo)
            {
            }

            private void OnExitingHandler1(StateChangeGuardInfo<AuthenticationState> changeinfo)
            {
            }

            private void ChangedHandler1(StateChangeInfo<AuthenticationState> changeinfo)
            {
            }
        }

        public class AnotherAuthenticationStateDefinition : StateDefinition<AuthenticationState>
        {
            public override void Define(IStateFromBuilder<AuthenticationState> builder)
            {
                builder.From(AuthenticationState.Unauthenticated).To(AuthenticationState.Authenticated)
                    .Changing(this, a => a.ChangingHandler2);

            }

            private void ChangingHandler2(StateChangeGuardInfo<AuthenticationState> changeinfo)
            {
                var data = changeinfo.DataAs<Dictionary<string, object>>();
                data["key2"] = "ChangingHandler2";
            }
        }
    }

    public enum AuthenticationState
    {
        Unauthenticated,
        Authenticated
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.