mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +08:00
feat(events): 为优先级事件系统添加线程安全支持
- 添加同步锁对象以保护处理器集合的并发访问 - 在注册和注销操作中加入线程安全锁机制 - 实现快照创建方法以避免迭代期间的并发修改 - 重构触发器逻辑以使用线程安全的快照创建 - 在计数器方法中添加同步保护 - 确保所有集合操作都在安全锁内执行
This commit is contained in:
parent
b5c67850ce
commit
d7e7d3cc7f
@ -18,6 +18,11 @@ public class PriorityEvent<T> : IEvent
|
||||
/// </summary>
|
||||
private readonly List<EventHandler> _handlers = new();
|
||||
|
||||
/// <summary>
|
||||
/// 保护处理器集合的并发访问
|
||||
/// </summary>
|
||||
private readonly object _syncRoot = new();
|
||||
|
||||
/// <summary>
|
||||
/// 标记事件是否已被处理(用于 UntilHandled 传播模式)
|
||||
/// </summary>
|
||||
@ -52,10 +57,13 @@ public class PriorityEvent<T> : IEvent
|
||||
public IUnRegister Register(Action<T> onEvent, int priority)
|
||||
{
|
||||
var handler = new EventHandler(onEvent, priority);
|
||||
_handlers.Add(handler);
|
||||
lock (_syncRoot)
|
||||
{
|
||||
_handlers.Add(handler);
|
||||
|
||||
// 按优先级降序排序(高优先级在前)
|
||||
_handlers.Sort((a, b) => b.Priority.CompareTo(a.Priority));
|
||||
// 按优先级降序排序(高优先级在前)
|
||||
_handlers.Sort((a, b) => b.Priority.CompareTo(a.Priority));
|
||||
}
|
||||
|
||||
return new DefaultUnRegister(() => UnRegister(onEvent));
|
||||
}
|
||||
@ -66,7 +74,10 @@ public class PriorityEvent<T> : IEvent
|
||||
/// <param name="onEvent">需要被注销的事件处理方法</param>
|
||||
public void UnRegister(Action<T> onEvent)
|
||||
{
|
||||
_handlers.RemoveAll(h => h.Handler == onEvent);
|
||||
lock (_syncRoot)
|
||||
{
|
||||
_handlers.RemoveAll(h => h.Handler == onEvent);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -78,10 +89,13 @@ public class PriorityEvent<T> : IEvent
|
||||
public IUnRegister RegisterWithContext(Action<EventContext<T>> onEvent, int priority = 0)
|
||||
{
|
||||
var handler = new ContextEventHandler(onEvent, priority);
|
||||
_contextHandlers.Add(handler);
|
||||
lock (_syncRoot)
|
||||
{
|
||||
_contextHandlers.Add(handler);
|
||||
|
||||
// 按优先级降序排序(高优先级在前)
|
||||
_contextHandlers.Sort((a, b) => b.Priority.CompareTo(a.Priority));
|
||||
// 按优先级降序排序(高优先级在前)
|
||||
_contextHandlers.Sort((a, b) => b.Priority.CompareTo(a.Priority));
|
||||
}
|
||||
|
||||
return new DefaultUnRegister(() => UnRegisterContext(onEvent));
|
||||
}
|
||||
@ -92,7 +106,10 @@ public class PriorityEvent<T> : IEvent
|
||||
/// <param name="onEvent">需要被注销的事件处理方法</param>
|
||||
public void UnRegisterContext(Action<EventContext<T>> onEvent)
|
||||
{
|
||||
_contextHandlers.RemoveAll(h => h.Handler == onEvent);
|
||||
lock (_syncRoot)
|
||||
{
|
||||
_contextHandlers.RemoveAll(h => h.Handler == onEvent);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -172,8 +189,7 @@ public class PriorityEvent<T> : IEvent
|
||||
/// <param name="t">事件参数</param>
|
||||
private void TriggerHighest(T t)
|
||||
{
|
||||
var normalSnapshot = _handlers.ToArray();
|
||||
var contextSnapshot = _contextHandlers.ToArray();
|
||||
var (normalSnapshot, contextSnapshot) = CreateSnapshots();
|
||||
var highestPriority = GetHighestPriority(normalSnapshot, contextSnapshot);
|
||||
|
||||
if (highestPriority != int.MinValue)
|
||||
@ -191,8 +207,7 @@ public class PriorityEvent<T> : IEvent
|
||||
private List<(int Priority, Action? Handler, Action<EventContext<T>>? ContextHandler, bool IsContext)>
|
||||
MergeAndSortHandlers(T t)
|
||||
{
|
||||
var normalSnapshot = _handlers.ToArray();
|
||||
var contextSnapshot = _contextHandlers.ToArray();
|
||||
var (normalSnapshot, contextSnapshot) = CreateSnapshots();
|
||||
// 使用快照避免迭代期间修改
|
||||
return normalSnapshot
|
||||
.Select(h => (h.Priority, Handler: (Action?)(() => h.Handler.Invoke(t)),
|
||||
@ -260,7 +275,18 @@ public class PriorityEvent<T> : IEvent
|
||||
/// <returns>监听器总数量</returns>
|
||||
public int GetListenerCount()
|
||||
{
|
||||
return _handlers.Count + _contextHandlers.Count;
|
||||
lock (_syncRoot)
|
||||
{
|
||||
return _handlers.Count + _contextHandlers.Count;
|
||||
}
|
||||
}
|
||||
|
||||
private (EventHandler[] NormalHandlers, ContextEventHandler[] ContextHandlers) CreateSnapshots()
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
return (_handlers.ToArray(), _contextHandlers.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user