From 1f1aff5335c00f8d9daa982e36f1f2834650c902 Mon Sep 17 00:00:00 2001 From: GeWuYou <95328647+GeWuYou@users.noreply.github.com> Date: Mon, 23 Mar 2026 20:58:03 +0800 Subject: [PATCH] =?UTF-8?q?refactor(state):=20=E4=BC=98=E5=8C=96=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E7=AE=A1=E7=90=86=E5=AD=98=E5=82=A8=E7=9A=84=E4=B8=AD?= =?UTF-8?q?=E9=97=B4=E4=BB=B6=E5=92=8Creducer=E5=BF=AB=E7=85=A7=E5=88=9B?= =?UTF-8?q?=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 为CreateMiddlewareSnapshot方法添加状态锁保护 - 为CreateReducerSnapshot方法添加状态锁保护 - 更新方法注释说明锁的安全性保障机制 - 避免调用方需要了解锁顺序的隐式依赖关系 --- GFramework.Core/StateManagement/Store.cs | 47 ++++++++++++++---------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/GFramework.Core/StateManagement/Store.cs b/GFramework.Core/StateManagement/Store.cs index 73cb5c6..677c6f3 100644 --- a/GFramework.Core/StateManagement/Store.cs +++ b/GFramework.Core/StateManagement/Store.cs @@ -617,45 +617,52 @@ public sealed class Store : IStore, IStoreDiagnostics /// /// 为当前中间件链创建快照。 - /// Dispatch 在离开状态锁前复制列表,以便后续在锁外执行稳定、不可变的中间件序列。 + /// 该方法自行获取状态锁,避免调用方必须记住“只能在已加锁条件下调用”这一隐含约束, + /// 从而降低未来重构时把它误用到锁外路径中的风险。 /// /// 当前中间件链的快照;若未注册则返回空数组。 private IStoreMiddleware[] CreateMiddlewareSnapshot() { - if (_middlewares.Count == 0) + lock (_lock) { - return Array.Empty>(); - } + if (_middlewares.Count == 0) + { + return Array.Empty>(); + } - var snapshot = new IStoreMiddleware[_middlewares.Count]; - for (var i = 0; i < _middlewares.Count; i++) - { - snapshot[i] = _middlewares[i].Middleware; - } + var snapshot = new IStoreMiddleware[_middlewares.Count]; + for (var i = 0; i < _middlewares.Count; i++) + { + snapshot[i] = _middlewares[i].Middleware; + } - return snapshot; + return snapshot; + } } /// /// 为当前 action 类型创建 reducer 快照。 - /// Dispatch 在离开状态锁前复制列表,以便后续在锁外执行稳定、不可变的 reducer 序列。 + /// 该方法自行获取状态锁,避免让快照安全性依赖调用方的锁顺序知识。 /// /// 当前分发的 action 类型。 /// 对应 action 类型的 reducer 快照;若未注册则返回空数组。 private IStoreReducerAdapter[] CreateReducerSnapshot(Type actionType) { - if (!_reducers.TryGetValue(actionType, out var reducers) || reducers.Count == 0) + lock (_lock) { - return Array.Empty(); - } + if (!_reducers.TryGetValue(actionType, out var reducers) || reducers.Count == 0) + { + return Array.Empty(); + } - var snapshot = new IStoreReducerAdapter[reducers.Count]; - for (var i = 0; i < reducers.Count; i++) - { - snapshot[i] = reducers[i].Adapter; - } + var snapshot = new IStoreReducerAdapter[reducers.Count]; + for (var i = 0; i < reducers.Count; i++) + { + snapshot[i] = reducers[i].Adapter; + } - return snapshot; + return snapshot; + } } ///