mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +08:00
feat(state): 实现异步状态基类的同步方法限制
- 为 AsyncContextAwareStateBase 添加同步方法异常抛出机制 - 禁止在异步状态中使用 OnEnter、OnExit 和 CanTransitionTo 同步方法 - 提供清晰的错误提示引导使用对应的异步方法 - 修复 StateMachine 中的状态转换逻辑确保线程安全 - 更新 IAsyncState 接口继承 IState 接口统一状态管理
This commit is contained in:
parent
38967d047a
commit
22c1d08dc3
@ -16,7 +16,7 @@ namespace GFramework.Core.Abstractions.state;
|
||||
/// <summary>
|
||||
/// 异步状态机状态接口,定义了状态的异步行为和转换规则
|
||||
/// </summary>
|
||||
public interface IAsyncState
|
||||
public interface IAsyncState : IState
|
||||
{
|
||||
/// <summary>
|
||||
/// 当状态被激活进入时异步调用
|
||||
|
||||
@ -61,6 +61,39 @@ public class AsyncContextAwareStateBase : IAsyncState, IContextAware, IDisposabl
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同步进入状态(不推荐使用)
|
||||
/// 异步状态应该使用 OnEnterAsync 方法
|
||||
/// </summary>
|
||||
/// <exception cref="NotSupportedException">异步状态不支持同步操作</exception>
|
||||
public virtual void OnEnter(IState? from)
|
||||
{
|
||||
throw new NotSupportedException(
|
||||
$"This is an async state ({GetType().Name}). Use OnEnterAsync instead of OnEnter.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同步退出状态(不推荐使用)
|
||||
/// 异步状态应该使用 OnExitAsync 方法
|
||||
/// </summary>
|
||||
/// <exception cref="NotSupportedException">异步状态不支持同步操作</exception>
|
||||
public virtual void OnExit(IState? to)
|
||||
{
|
||||
throw new NotSupportedException(
|
||||
$"This is an async state ({GetType().Name}). Use OnExitAsync instead of OnExit.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同步判断是否可以转换(不推荐使用)
|
||||
/// 异步状态应该使用 CanTransitionToAsync 方法
|
||||
/// </summary>
|
||||
/// <exception cref="NotSupportedException">异步状态不支持同步操作</exception>
|
||||
public virtual bool CanTransitionTo(IState target)
|
||||
{
|
||||
throw new NotSupportedException(
|
||||
$"This is an async state ({GetType().Name}). Use CanTransitionToAsync instead of CanTransitionTo.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置架构上下文
|
||||
/// </summary>
|
||||
|
||||
@ -138,20 +138,23 @@ public class StateMachine(int maxHistorySize = 10) : IStateMachine
|
||||
public async Task<bool> ChangeToAsync<T>() where T : IState
|
||||
{
|
||||
IState target;
|
||||
IState? currentSnapshot;
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
if (!States.TryGetValue(typeof(T), out target!))
|
||||
throw new InvalidOperationException($"State {typeof(T).Name} not registered.");
|
||||
|
||||
currentSnapshot = Current; // 在锁内获取当前状态的快照
|
||||
}
|
||||
|
||||
// 验证转换(在锁外执行异步操作)
|
||||
if (Current != null)
|
||||
if (currentSnapshot != null)
|
||||
{
|
||||
var canTransition = await CanTransitionToAsync(Current, target);
|
||||
var canTransition = await CanTransitionToAsync(currentSnapshot, target);
|
||||
if (!canTransition)
|
||||
{
|
||||
await OnTransitionRejectedAsync(Current, target);
|
||||
await OnTransitionRejectedAsync(currentSnapshot, target);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user