【发布时间】:2010-11-27 06:40:36
【问题描述】:
我最近阅读了有关 boost::statechart 库(有限状态机)的信息,我喜欢这个概念。
C# 有类似的机制吗?还是可以使用特定的设计模式来实现?
【问题讨论】:
标签: c# .net design-patterns finite-automata fsm
我最近阅读了有关 boost::statechart 库(有限状态机)的信息,我喜欢这个概念。
C# 有类似的机制吗?还是可以使用特定的设计模式来实现?
【问题讨论】:
标签: c# .net design-patterns finite-automata fsm
此回购中的其他替代方案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
}
}
【讨论】:
查看无状态 -> http://code.google.com/p/stateless/。它是较重的 WWF 的轻量级替代品。
以下是该工具作者的几篇文章:
【讨论】:
.NET 4 Update 1 现在在以下类中支持它: System.Activities.Statements.StateMachine
【讨论】:
我维护了一个开源项目,它实现了(除其他外)一个通用的 .NET 有限状态机。它建立在QuickGraph 之上,因此您可以免费获得许多图形分析算法。
有关该项目的更多信息,请参阅this page,特别是“Jolt.Automata : Finite State Machines”以了解有关该功能的更多信息。
【讨论】:
作为 3.0 和 3.5 中基类库的一部分的 Windows Workflow Foundation (WF) 包含一个状态机工作流设计,用于管理应用程序的状态机。
他们为即将发布的 4.0 版本完全重写了工作流程,并且新的 WF 4.0 类本身不支持状态机,但 4.0 下仍然完全支持所有 3.0/3.5 类。
【讨论】:
接近 FSM 的是 .NET 3.5 中的工作流,但是,工作流也不完全是 FSM。
使用 FSM 的强大之处在于您可以在代码中显式地创建它们,从而减少产生错误的机会。此外,当然有些系统本质上是 FSM,所以这样编码更自然。
【讨论】:
Workflow Foundation (.NET 3.0) 有一个状态机工作流。 4.0 目前没有完全相同的东西,但是您绝对可以使用 4.0 创建状态机工作流。
【讨论】:
是的,C# 有 iterator blocks,它们是编译器生成的状态机。
如果您希望实现自己的状态机,您可以创建 IEnumerable<T> 和 IEnumerator<T> 接口的自定义实现。
这两种方法都突出了 .NET 框架对 iterator pattern 的实现。
【讨论】: