我是靠谱客的博主 甜美大门,这篇文章主要介绍C# 关于状态机的实现(案例版)阅,现在分享给大家,希望可以做个参考。

大部分的状态机都是有限状态机,某些业务环境,或者其他环境中,如果有状态机其实还是很方便的。比如,我是用在了单个客户的Socket通信上,未连接状态,我就等连接。已连接状态,就等待下一步指令状态。这样的,逻辑就会简化许多。

以前在C语言上,自己实现过状态机,但是,过去好久了。也想通过C#实现,看看是不是方便许多。

状态机的实现

状态机接口对象

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/// <summary> /// 状态对象 /// </summary> public interface IStateObject { /// <summary> /// 进入状态 /// </summary> void EnterState(); /// <summary> /// 离开状态 /// </summary> void ExitState(); /// <summary> /// 更新状态 /// </summary> void UpdateState(); }

也可以在 更新状态里,自己设置下一个状态。算是转到指定状态上。

比如登录成功

状态机核心逻辑

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/// <summary> /// 状态机 /// </summary> public class StateMachine { /// <summary> /// 运行 Update 时间间隔 毫秒 /// </summary> public int RunInterval = 500; /// <summary> /// 当前状态 /// </summary> private string CurrentState; /// <summary> /// 字典存放当前所有对象 /// </summary> private Dictionary<string, IStateObject> Dic = new(); /// <summary> /// 当前的线程对象 /// </summary> private Thread thread; /// <summary> /// 是否已经在运行 /// </summary> private bool IsRun = false; public StateMachine(int runInterval = 500) { this.RunInterval = runInterval; } /// <summary> /// 注册一个状态对象 /// </summary> /// <param name="stateObject"></param> /// <param name="istateObject"></param> public void Register(string stateObject, IStateObject istateObject) { Dic.TryAdd(stateObject, istateObject); } /// <summary> /// 注册一个状态对象 /// </summary> /// <param name="stateObject"></param> /// <param name="istateObject"></param> public void Register(Dictionary<string, IStateObject> stateObjects) { if (stateObjects?.Any() == true) { foreach (var item in stateObjects) { Dic.TryAdd(item.Key, item.Value); } } } /// <summary> /// 设置当前状态 /// </summary> /// <param name="stateObject"></param> public void SetState(string stateObject) { if (CurrentState != stateObject) { if (CurrentState != null && Dic.TryGetValue(CurrentState, out var oldObj)) { oldObj.ExitState(); } CurrentState = stateObject; if (CurrentState != null && Dic.TryGetValue(CurrentState, out var newObj)) { newObj.EnterState(); } } } /// <summary> /// 自己启动服务 /// </summary> public void Start() { if (!IsRun) { IsRun = true; thread = new Thread(new ThreadStart(Run)); thread.IsBackground = true; thread.Start(); Console.WriteLine("状态机启动"); } } /// <summary> /// 自己停止服务 /// </summary> public void Close() { if (IsRun) { //最后一个状态直接退出 if (CurrentState != null && Dic.TryGetValue(CurrentState, out var oldObj)) { oldObj.ExitState(); } IsRun = false; try { thread.Interrupt(); } catch (Exception) { } Thread.Sleep(50); thread = null; Console.WriteLine("状态机关闭"); } } /// <summary> /// 线程执行的任务 /// </summary> private void Run() { try { while (IsRun) { Updata(); SpinWait.SpinUntil(() => !IsRun, RunInterval); } } catch (Exception) { }; } /// <summary> /// 更新数据 /// </summary> public void Updata() { if (CurrentState != null && Dic.TryGetValue(CurrentState, out var objobj)) { objobj.UpdateState(); } } }

这个是状态机的核心实现,大佬随便看一下应该就知道啥意思了。

定义两个状态对象

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/// <summary> /// 一只猫 /// </summary> public class Cat : IStateObject { public void EnterState() { Console.WriteLine("小猫进来了"); } public void ExitState() { Console.WriteLine("小猫出去了"); } public void UpdateState() { Console.WriteLine("小猫在玩逗猫棒!"); } }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/// <summary> /// 一只狗 /// </summary> public class Dog : IStateObject { public void EnterState() { Console.WriteLine("小狗进来了"); } public void ExitState() { Console.WriteLine("小狗出去了"); } public void UpdateState() { Console.WriteLine("小狗在玩耍!"); } }

一只猫,一只狗,就可以切换状态效果了。

测试代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
static void Main(string[] args) { StateMachine stateMachine = new StateMachine(1500); //状态机 //根据当前的不同的状态,做出不同的事件操作 stateMachine.Register(nameof(Cat), new Cat()); stateMachine.Register(nameof(Dog), new Dog()); //启动状态机 stateMachine.Start(); //开始执行状态机 //设置当前状态 stateMachine.SetState(nameof(Cat)); Thread.Sleep(2000); stateMachine.SetState(nameof(Dog)); Thread.Sleep(2000); stateMachine.SetState(nameof(Cat)); Thread.Sleep(2000); //状态机停止 stateMachine.Close(); Console.WriteLine("状态机执行完毕!"); Console.ReadLine(); }

运行结果

总结

状态机C#实现完之后,用着还是挺方便的。对于有些流程也可以用状态机来实现。

代码地址

https://github.com/kesshei/StateMachineDemo.git

https://gitee.com/kesshei/StateMachineDemo.git

一键三连呦!,感谢大佬的支持,您的支持就是我的动力!

最后

以上就是甜美大门最近收集整理的关于C# 关于状态机的实现(案例版)阅的全部内容,更多相关C#内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(62)

评论列表共有 0 条评论

立即
投稿
返回
顶部