fix(core): 迁移 MA0158 专用锁实现

- 迁移 Events、Property、State 与 Coroutine 中 7 个类型的监视器字段到 NET9_0_OR_GREATER 专用 Lock 模式
- 保持 net8.0 的 object 回退路径以兼容多目标构建
- 更新 BindableProperty 的同步注释以匹配新的多目标同步原语
This commit is contained in:
gewuyou 2026-04-27 07:42:20 +08:00
parent e3eec5452c
commit 8f2d95910e
7 changed files with 47 additions and 5 deletions

View File

@ -12,7 +12,13 @@ internal sealed class CoroutineStatistics : ICoroutineStatistics
{ {
private readonly Dictionary<CoroutinePriority, int> _countByPriority = new(); private readonly Dictionary<CoroutinePriority, int> _countByPriority = new();
private readonly Dictionary<string, int> _countByTag = new(StringComparer.Ordinal); private readonly Dictionary<string, int> _countByTag = new(StringComparer.Ordinal);
#if NET9_0_OR_GREATER
// net9.0 及以上目标使用专用 Lock以满足分析器对专用同步原语的建议。
private readonly System.Threading.Lock _lock = new();
#else
// net8.0 目标仍回退到 object 锁,以保持多目标编译兼容性。
private readonly object _lock = new(); private readonly object _lock = new();
#endif
private int _activeCount; private int _activeCount;
private double _maxExecutionTimeMs; private double _maxExecutionTimeMs;
private int _pausedCount; private int _pausedCount;

View File

@ -10,7 +10,13 @@ namespace GFramework.Core.Events;
public sealed class EventStatistics : IEventStatistics public sealed class EventStatistics : IEventStatistics
{ {
private readonly Dictionary<string, int> _listenerCountByType = new(StringComparer.Ordinal); private readonly Dictionary<string, int> _listenerCountByType = new(StringComparer.Ordinal);
#if NET9_0_OR_GREATER
// net9.0 及以上目标使用专用 Lock以满足分析器对专用同步原语的建议。
private readonly System.Threading.Lock _lock = new();
#else
// net8.0 目标仍回退到 object 锁,以保持多目标编译兼容性。
private readonly object _lock = new(); private readonly object _lock = new();
#endif
private readonly Dictionary<string, long> _publishCountByType = new(StringComparer.Ordinal); private readonly Dictionary<string, long> _publishCountByType = new(StringComparer.Ordinal);
private long _totalFailed; private long _totalFailed;
private long _totalHandled; private long _totalHandled;

View File

@ -10,7 +10,13 @@ namespace GFramework.Core.Events;
public sealed class FilterableEvent<T> public sealed class FilterableEvent<T>
{ {
private readonly List<IEventFilter<T>> _filters = new(); private readonly List<IEventFilter<T>> _filters = new();
#if NET9_0_OR_GREATER
// net9.0 及以上目标使用专用 Lock以满足分析器对专用同步原语的建议。
private readonly System.Threading.Lock _lock = new();
#else
// net8.0 目标仍回退到 object 锁,以保持多目标编译兼容性。
private readonly object _lock = new(); private readonly object _lock = new();
#endif
private readonly EventStatistics? _statistics; private readonly EventStatistics? _statistics;
private Action<T>? _onEvent; private Action<T>? _onEvent;
@ -152,4 +158,4 @@ public sealed class FilterableEvent<T>
var count = _onEvent?.GetInvocationList().Length ?? 0; var count = _onEvent?.GetInvocationList().Length ?? 0;
_statistics.UpdateListenerCount(typeof(T).Name, count); _statistics.UpdateListenerCount(typeof(T).Name, count);
} }
} }

View File

@ -21,7 +21,13 @@ public class PriorityEvent<T> : IEvent
/// <summary> /// <summary>
/// 保护处理器集合的并发访问 /// 保护处理器集合的并发访问
/// </summary> /// </summary>
#if NET9_0_OR_GREATER
// net9.0 及以上目标使用专用 Lock以满足分析器对专用同步原语的建议。
private readonly System.Threading.Lock _syncRoot = new();
#else
// net8.0 目标仍回退到 object 锁,以保持多目标编译兼容性。
private readonly object _syncRoot = new(); private readonly object _syncRoot = new();
#endif
/// <summary> /// <summary>
/// 标记事件是否已被处理(用于 UntilHandled 传播模式) /// 标记事件是否已被处理(用于 UntilHandled 传播模式)
@ -326,4 +332,4 @@ public class PriorityEvent<T> : IEvent
public Action<EventContext<T>> Handler { get; } = handler; public Action<EventContext<T>> Handler { get; } = handler;
public int Priority { get; } = priority; public int Priority { get; } = priority;
} }
} }

View File

@ -10,7 +10,13 @@ namespace GFramework.Core.Events;
/// <typeparam name="T">事件数据类型</typeparam> /// <typeparam name="T">事件数据类型</typeparam>
public sealed class WeakEvent<T> public sealed class WeakEvent<T>
{ {
#if NET9_0_OR_GREATER
// net9.0 及以上目标使用专用 Lock以满足分析器对专用同步原语的建议。
private readonly System.Threading.Lock _lock = new();
#else
// net8.0 目标仍回退到 object 锁,以保持多目标编译兼容性。
private readonly object _lock = new(); private readonly object _lock = new();
#endif
private readonly EventStatistics? _statistics; private readonly EventStatistics? _statistics;
private readonly List<WeakReference<Action<T>>> _weakHandlers = new(); private readonly List<WeakReference<Action<T>>> _weakHandlers = new();
@ -151,4 +157,4 @@ public sealed class WeakEvent<T>
var count = _weakHandlers.Count(wr => wr.TryGetTarget(out _)); var count = _weakHandlers.Count(wr => wr.TryGetTarget(out _));
_statistics.UpdateListenerCount(typeof(T).Name, count); _statistics.UpdateListenerCount(typeof(T).Name, count);
} }
} }

View File

@ -12,9 +12,15 @@ namespace GFramework.Core.Property;
public class BindableProperty<T>(T defaultValue = default!) : IBindableProperty<T> public class BindableProperty<T>(T defaultValue = default!) : IBindableProperty<T>
{ {
/// <summary> /// <summary>
/// 用于保护委托链和值访问的锁对象 /// 用于保护委托链和值访问的同步原语
/// </summary> /// </summary>
#if NET9_0_OR_GREATER
// net9.0 及以上目标使用专用 Lock以满足分析器对专用同步原语的建议。
private readonly System.Threading.Lock _lock = new();
#else
// net8.0 目标仍回退到 object 锁,以保持多目标编译兼容性。
private readonly object _lock = new(); private readonly object _lock = new();
#endif
/// <summary> /// <summary>
/// 属性值变化事件回调委托,当属性值发生变化时被调用 /// 属性值变化事件回调委托,当属性值发生变化时被调用
@ -172,4 +178,4 @@ public class BindableProperty<T>(T defaultValue = default!) : IBindableProperty<
{ {
return Value?.ToString() ?? string.Empty; return Value?.ToString() ?? string.Empty;
} }
} }

View File

@ -8,7 +8,13 @@ namespace GFramework.Core.State;
/// </summary> /// </summary>
public class StateMachine(int maxHistorySize = 10) : IStateMachine public class StateMachine(int maxHistorySize = 10) : IStateMachine
{ {
#if NET9_0_OR_GREATER
// net9.0 及以上目标使用专用 Lock以满足分析器对专用同步原语的建议。
private readonly System.Threading.Lock _lock = new();
#else
// net8.0 目标仍回退到 object 锁,以保持多目标编译兼容性。
private readonly object _lock = new(); private readonly object _lock = new();
#endif
private readonly HashSet<IState> _registeredStates = []; private readonly HashSet<IState> _registeredStates = [];
private readonly Stack<IState> _stateHistory = new(); private readonly Stack<IState> _stateHistory = new();