C# 是否包括有限状态机?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1406986/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does C# include finite state machines?
提问by Maciek
I've recently read about the boost::statechart
library (finite state machines) and I loved the concept.
我最近阅读了有关boost::statechart
库(有限状态机)的文章,我很喜欢这个概念。
Does C# have a similar mechanism ? Or can it be implemented using a specific design pattern?
C# 有类似的机制吗?还是可以使用特定的设计模式来实现?
采纳答案by Andrew Hare
Yes, C# has iterator blockswhich are compiler-generated state machines.
是的,C# 有迭代器块,它们是编译器生成的状态机。
If you wish to implement you own state machine you can create custom implementations of the IEnumerable<T>
and IEnumerator<T>
interfaces.
如果您希望实现自己的状态机,您可以创建IEnumerable<T>
和IEnumerator<T>
接口的自定义实现。
Both of these approaches highlight the .NET framework's implementation of the iterator pattern.
这两种方法都突出了 .NET 框架对迭代器模式的实现。
回答by Andrew Hare
Workflow Foundation (.NET 3.0)has a state machine workflow. 4.0 doesn't have exactly the same thing currently, but you can definitely create a state machine workflow using 4.0.
Workflow Foundation (.NET 3.0)有一个状态机工作流。4.0 目前没有完全相同的东西,但您绝对可以使用 4.0 创建状态机工作流。
回答by Henri
The things that come near to FSMs are workflows in .NET 3.5, however, also workflows are not exactly FSMs.
接近 FSM 的是 .NET 3.5 中的工作流,但是,工作流也不完全是 FSM。
The power of using FSMs is that you can create them explicitlyin your code, having less chance of creating bugs. Besides, of course some systems are FSMs by nature, so it is more natural to code them like so.
使用 FSM 的强大之处在于您可以在代码中显式地创建它们,从而减少产生错误的机会。此外,当然有些系统本质上是 FSM,所以像这样编码它们更自然。
回答by Steve Guidi
I maintain an open-source project which implements (among other things) a generic finite state machine for .NET. It is built on top of QuickGraph, so you get many graph-analysis algorithms for free.
我维护一个开源项目,该项目为 .NET 实现(除其他外)通用有限状态机。它建立在QuickGraph之上,因此您可以免费获得许多图形分析算法。
See this pagefor more information about the project, and specifically "Jolt.Automata : Finite State Machines" for more information about the feature.
有关该项目的更多信息,请参阅此页面,特别是“ Jolt.Automata : Finite State Machines”以获取有关该功能的更多信息。
回答by Bytemaster
Windows Workflow Foundation (WF) that is part of the base class library in 3.0 and 3.5 includes a state-machine workflow design to manage state machines for your applications.
作为 3.0 和 3.5 中基类库的一部分的 Windows Workflow Foundation (WF) 包括一个状态机工作流设计,用于管理应用程序的状态机。
They have completely rewritten workflow for the upcoming 4.0 release, and the new WF 4.0 classes do not natively support state-machines, but all of the 3.0/3.5 classes are still fully supported under 4.0.
他们为即将发布的 4.0 版本完全重写了工作流程,新的 WF 4.0 类本身不支持状态机,但在 4.0 下仍然完全支持所有 3.0/3.5 类。
回答by Alex
.NET 4 Update 1 now supports it in the following class: System.Activities.Statements.StateMachine
.NET 4 Update 1 现在在以下类中支持它: System.Activities.Statements.StateMachine
Here is a tutorial on how to use it. Here's a hands on lab.
回答by J.D.
Check out Stateless -> http://code.google.com/p/stateless/. Its a lightweight alternative to the heavier WWF.
查看无状态 -> http://code.google.com/p/stateless/。它是较重的 WWF 的轻量级替代品。
Here's a couple of articles by the author of the tool:
以下是该工具作者的几篇文章:
State Machines in Domain Models
回答by mcdm
Other alternative in this repo https://github.com/lingkodsoft/StateBlissused fluent syntax, supports triggers.
此 repo 中的其他替代方案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
}
}