feat(event): 添加事件统计功能和优化性能

- 在EasyEventGeneric中添加GetListenerCount方法获取监听器数量
- 重新排列EnhancedEventBus中字段顺序以优化内存布局
- 为所有Send方法添加发布统计记录功能
- 实现事件处理器包装以添加统计功能,包括成功处理和失败记录
- 添加监听器数量统计更新机制,自动跟踪注册和注销事件
- 重构FilterableEvent中的过滤逻辑以减少锁持有时间
- 在PriorityEvent中添加GetListenerCount方法获取总监听器数量
- 移除EventStatistics中的过时字段并优化ActiveEventTypes和ActiveListeners计算
- 清理StatisticsEventDecorator中的并发问题和实现装饰器模式
This commit is contained in:
GeWuYou 2026-03-06 16:40:54 +08:00
parent e738e59a58
commit 5ef464c484
6 changed files with 306 additions and 17 deletions

View File

@ -59,6 +59,15 @@ public class Event<T> : IEvent
{
_mOnEvent?.Invoke(t);
}
/// <summary>
/// 获取当前已注册的监听器数量
/// </summary>
/// <returns>监听器数量</returns>
public int GetListenerCount()
{
return _mOnEvent?.GetInvocationList().Length ?? 0;
}
}
/// <summary>
@ -120,4 +129,13 @@ public class Event<T, Tk> : IEvent
{
_mOnEvent?.Invoke(t, k);
}
/// <summary>
/// 获取当前已注册的监听器数量
/// </summary>
/// <returns>监听器数量</returns>
public int GetListenerCount()
{
return _mOnEvent?.GetInvocationList().Length ?? 0;
}
}

View File

@ -37,6 +37,8 @@ public sealed class EnhancedEventBus : IEventBus
/// <typeparam name="T">事件类型</typeparam>
public void Send<T>() where T : new()
{
_statistics?.RecordPublish(typeof(T).Name);
_mEvents
.GetOrAddEvent<Event<T>>()
.Trigger(new T());
@ -49,6 +51,8 @@ public sealed class EnhancedEventBus : IEventBus
/// <param name="e">事件实例</param>
public void Send<T>(T e)
{
_statistics?.RecordPublish(typeof(T).Name);
_mEvents
.GetOrAddEvent<Event<T>>()
.Trigger(e);
@ -62,6 +66,8 @@ public sealed class EnhancedEventBus : IEventBus
/// <param name="propagation">事件传播方式</param>
public void Send<T>(T e, EventPropagation propagation)
{
_statistics?.RecordPublish(typeof(T).Name);
_mPriorityEvents
.GetOrAddEvent<PriorityEvent<T>>()
.Trigger(e, propagation);
@ -75,6 +81,32 @@ public sealed class EnhancedEventBus : IEventBus
/// <returns>反注册接口,用于取消订阅</returns>
public IUnRegister Register<T>(Action<T> onEvent)
{
if (_statistics != null)
{
// 包装回调以添加统计
Action<T> wrappedHandler = data =>
{
try
{
onEvent(data);
_statistics.RecordHandle();
}
catch
{
_statistics.RecordFailure();
throw;
}
};
var unregister = _mEvents.GetOrAddEvent<Event<T>>().Register(wrappedHandler);
UpdateEventListenerCount<T>();
return new DefaultUnRegister(() =>
{
unregister.UnRegister();
UpdateEventListenerCount<T>();
});
}
return _mEvents.GetOrAddEvent<Event<T>>().Register(onEvent);
}
@ -87,6 +119,32 @@ public sealed class EnhancedEventBus : IEventBus
/// <returns>反注册接口,用于取消订阅</returns>
public IUnRegister Register<T>(Action<T> onEvent, int priority)
{
if (_statistics != null)
{
// 包装回调以添加统计
Action<T> wrappedHandler = data =>
{
try
{
onEvent(data);
_statistics.RecordHandle();
}
catch
{
_statistics.RecordFailure();
throw;
}
};
var unregister = _mPriorityEvents.GetOrAddEvent<PriorityEvent<T>>().Register(wrappedHandler, priority);
UpdatePriorityEventListenerCount<T>();
return new DefaultUnRegister(() =>
{
unregister.UnRegister();
UpdatePriorityEventListenerCount<T>();
});
}
return _mPriorityEvents.GetOrAddEvent<PriorityEvent<T>>().Register(onEvent, priority);
}
@ -98,6 +156,7 @@ public sealed class EnhancedEventBus : IEventBus
public void UnRegister<T>(Action<T> onEvent)
{
_mEvents.GetEvent<Event<T>>().UnRegister(onEvent);
UpdateEventListenerCount<T>();
}
/// <summary>
@ -108,6 +167,32 @@ public sealed class EnhancedEventBus : IEventBus
/// <returns>反注册接口,用于取消订阅</returns>
public IUnRegister RegisterWithContext<T>(Action<EventContext<T>> onEvent)
{
if (_statistics != null)
{
// 包装回调以添加统计
Action<EventContext<T>> wrappedHandler = context =>
{
try
{
onEvent(context);
_statistics.RecordHandle();
}
catch
{
_statistics.RecordFailure();
throw;
}
};
var unregister = _mPriorityEvents.GetOrAddEvent<PriorityEvent<T>>().RegisterWithContext(wrappedHandler);
UpdatePriorityEventListenerCount<T>();
return new DefaultUnRegister(() =>
{
unregister.UnRegister();
UpdatePriorityEventListenerCount<T>();
});
}
return _mPriorityEvents.GetOrAddEvent<PriorityEvent<T>>().RegisterWithContext(onEvent);
}
@ -120,6 +205,33 @@ public sealed class EnhancedEventBus : IEventBus
/// <returns>反注册接口,用于取消订阅</returns>
public IUnRegister RegisterWithContext<T>(Action<EventContext<T>> onEvent, int priority)
{
if (_statistics != null)
{
// 包装回调以添加统计
Action<EventContext<T>> wrappedHandler = context =>
{
try
{
onEvent(context);
_statistics.RecordHandle();
}
catch
{
_statistics.RecordFailure();
throw;
}
};
var unregister = _mPriorityEvents.GetOrAddEvent<PriorityEvent<T>>()
.RegisterWithContext(wrappedHandler, priority);
UpdatePriorityEventListenerCount<T>();
return new DefaultUnRegister(() =>
{
unregister.UnRegister();
UpdatePriorityEventListenerCount<T>();
});
}
return _mPriorityEvents.GetOrAddEvent<PriorityEvent<T>>().RegisterWithContext(onEvent, priority);
}
@ -239,4 +351,40 @@ public sealed class EnhancedEventBus : IEventBus
}
#endregion
#region Helper Methods
/// <summary>
/// 更新普通事件的监听器数量统计
/// </summary>
private void UpdateEventListenerCount<T>()
{
if (_statistics == null)
return;
var evt = _mEvents.GetEvent<Event<T>>();
if (evt != null)
{
var count = evt.GetListenerCount();
_statistics.UpdateListenerCount(typeof(T).Name, count);
}
}
/// <summary>
/// 更新优先级事件的监听器数量统计
/// </summary>
private void UpdatePriorityEventListenerCount<T>()
{
if (_statistics == null)
return;
var evt = _mPriorityEvents.GetEvent<PriorityEvent<T>>();
if (evt != null)
{
var count = evt.GetListenerCount();
_statistics.UpdateListenerCount(typeof(T).Name, count);
}
}
#endregion
}

View File

@ -12,8 +12,6 @@ public sealed class EventStatistics : IEventStatistics
private readonly Dictionary<string, int> _listenerCountByType = new();
private readonly object _lock = new();
private readonly Dictionary<string, long> _publishCountByType = new();
private int _activeEventTypes;
private int _activeListeners;
private long _totalFailed;
private long _totalHandled;
private long _totalPublished;
@ -30,15 +28,25 @@ public sealed class EventStatistics : IEventStatistics
/// <inheritdoc />
public int ActiveEventTypes
{
get => Interlocked.CompareExchange(ref _activeEventTypes, 0, 0);
set => Interlocked.Exchange(ref _activeEventTypes, value);
get
{
lock (_lock)
{
return _publishCountByType.Count;
}
}
}
/// <inheritdoc />
public int ActiveListeners
{
get => Interlocked.CompareExchange(ref _activeListeners, 0, 0);
set => Interlocked.Exchange(ref _activeListeners, value);
get
{
lock (_lock)
{
return _listenerCountByType.Values.Sum();
}
}
}
/// <inheritdoc />
@ -65,8 +73,6 @@ public sealed class EventStatistics : IEventStatistics
Interlocked.Exchange(ref _totalPublished, 0);
Interlocked.Exchange(ref _totalHandled, 0);
Interlocked.Exchange(ref _totalFailed, 0);
Interlocked.Exchange(ref _activeEventTypes, 0);
Interlocked.Exchange(ref _activeListeners, 0);
lock (_lock)
{

View File

@ -61,21 +61,21 @@ public sealed class FilterableEvent<T>
// 记录发布统计
_statistics?.RecordPublish(typeof(T).Name);
// 应用过滤器
lock (_lock)
{
// 事件被过滤,不触发监听器
if (_filters.Any(filter => filter.ShouldFilter(data)))
return;
}
// 获取当前监听器快照(在锁外调用)
// 在单个锁中快照过滤器和监听器
Action<T>? handlers;
IEventFilter<T>[] filtersSnapshot;
lock (_lock)
{
filtersSnapshot = _filters.Count > 0 ? _filters.ToArray() : Array.Empty<IEventFilter<T>>();
handlers = _onEvent;
}
// 在锁外执行过滤逻辑
// 事件被过滤,不触发监听器
if (filtersSnapshot.Any(filter => filter.ShouldFilter(data)))
return;
if (handlers == null)
return;

View File

@ -254,6 +254,15 @@ public class PriorityEvent<T> : IEvent
}
}
/// <summary>
/// 获取当前已注册的监听器总数量(包括普通监听器和上下文监听器)
/// </summary>
/// <returns>监听器总数量</returns>
public int GetListenerCount()
{
return _handlers.Count + _contextHandlers.Count;
}
/// <summary>
/// 事件处理器包装类,包含处理器和优先级
/// </summary>

View File

@ -0,0 +1,108 @@
using GFramework.Core.Abstractions.events;
namespace GFramework.Core.events;
/// <summary>
/// 带统计功能的事件装饰器
/// 使用装饰器模式为任何 IEvent 实现添加统计功能
/// </summary>
/// <typeparam name="T">事件数据类型</typeparam>
internal sealed class StatisticsEventDecorator<T>
{
private readonly string _eventTypeName;
private readonly IEvent _innerEvent;
private readonly EventStatistics _statistics;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="innerEvent">被装饰的事件对象</param>
/// <param name="statistics">统计对象</param>
public StatisticsEventDecorator(IEvent innerEvent, EventStatistics statistics)
{
_innerEvent = innerEvent ?? throw new ArgumentNullException(nameof(innerEvent));
_statistics = statistics ?? throw new ArgumentNullException(nameof(statistics));
_eventTypeName = typeof(T).Name;
}
/// <summary>
/// 注册事件监听器(带统计)
/// </summary>
/// <param name="onEvent">事件处理回调</param>
/// <returns>反注册接口</returns>
public IUnRegister Register(Action<T> onEvent)
{
// 包装回调以添加统计
Action<T> wrappedHandler = data =>
{
try
{
onEvent(data);
_statistics.RecordHandle();
}
catch
{
_statistics.RecordFailure();
throw;
}
};
var unregister = _innerEvent.Register(() => { }); // 占位,实际不使用
// 直接注册到内部事件
if (_innerEvent is Event<T> typedEvent)
{
unregister = typedEvent.Register(wrappedHandler);
}
else if (_innerEvent is PriorityEvent<T> priorityEvent)
{
unregister = priorityEvent.Register(wrappedHandler);
}
// 更新监听器统计
UpdateListenerCount();
return new DefaultUnRegister(() =>
{
unregister.UnRegister();
UpdateListenerCount();
});
}
/// <summary>
/// 触发事件(带统计)
/// </summary>
/// <param name="data">事件数据</param>
public void Trigger(T data)
{
_statistics.RecordPublish(_eventTypeName);
if (_innerEvent is Event<T> typedEvent)
{
typedEvent.Trigger(data);
}
else if (_innerEvent is PriorityEvent<T> priorityEvent)
{
priorityEvent.Trigger(data, EventPropagation.Continue);
}
}
/// <summary>
/// 更新监听器数量统计
/// </summary>
private void UpdateListenerCount()
{
var count = 0;
if (_innerEvent is Event<T> typedEvent)
{
count = typedEvent.GetListenerCount();
}
else if (_innerEvent is PriorityEvent<T> priorityEvent)
{
count = priorityEvent.GetListenerCount();
}
_statistics.UpdateListenerCount(_eventTypeName, count);
}
}