mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-25 13:33:28 +08:00
feat(event): 添加事件统计功能和优化性能
- 在EasyEventGeneric中添加GetListenerCount方法获取监听器数量 - 重新排列EnhancedEventBus中字段顺序以优化内存布局 - 为所有Send方法添加发布统计记录功能 - 实现事件处理器包装以添加统计功能,包括成功处理和失败记录 - 添加监听器数量统计更新机制,自动跟踪注册和注销事件 - 重构FilterableEvent中的过滤逻辑以减少锁持有时间 - 在PriorityEvent中添加GetListenerCount方法获取总监听器数量 - 移除EventStatistics中的过时字段并优化ActiveEventTypes和ActiveListeners计算 - 清理StatisticsEventDecorator中的并发问题和实现装饰器模式
This commit is contained in:
parent
e738e59a58
commit
5ef464c484
@ -59,6 +59,15 @@ public class Event<T> : IEvent
|
|||||||
{
|
{
|
||||||
_mOnEvent?.Invoke(t);
|
_mOnEvent?.Invoke(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前已注册的监听器数量
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>监听器数量</returns>
|
||||||
|
public int GetListenerCount()
|
||||||
|
{
|
||||||
|
return _mOnEvent?.GetInvocationList().Length ?? 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -120,4 +129,13 @@ public class Event<T, Tk> : IEvent
|
|||||||
{
|
{
|
||||||
_mOnEvent?.Invoke(t, k);
|
_mOnEvent?.Invoke(t, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前已注册的监听器数量
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>监听器数量</returns>
|
||||||
|
public int GetListenerCount()
|
||||||
|
{
|
||||||
|
return _mOnEvent?.GetInvocationList().Length ?? 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -37,6 +37,8 @@ public sealed class EnhancedEventBus : IEventBus
|
|||||||
/// <typeparam name="T">事件类型</typeparam>
|
/// <typeparam name="T">事件类型</typeparam>
|
||||||
public void Send<T>() where T : new()
|
public void Send<T>() where T : new()
|
||||||
{
|
{
|
||||||
|
_statistics?.RecordPublish(typeof(T).Name);
|
||||||
|
|
||||||
_mEvents
|
_mEvents
|
||||||
.GetOrAddEvent<Event<T>>()
|
.GetOrAddEvent<Event<T>>()
|
||||||
.Trigger(new T());
|
.Trigger(new T());
|
||||||
@ -49,6 +51,8 @@ public sealed class EnhancedEventBus : IEventBus
|
|||||||
/// <param name="e">事件实例</param>
|
/// <param name="e">事件实例</param>
|
||||||
public void Send<T>(T e)
|
public void Send<T>(T e)
|
||||||
{
|
{
|
||||||
|
_statistics?.RecordPublish(typeof(T).Name);
|
||||||
|
|
||||||
_mEvents
|
_mEvents
|
||||||
.GetOrAddEvent<Event<T>>()
|
.GetOrAddEvent<Event<T>>()
|
||||||
.Trigger(e);
|
.Trigger(e);
|
||||||
@ -62,6 +66,8 @@ public sealed class EnhancedEventBus : IEventBus
|
|||||||
/// <param name="propagation">事件传播方式</param>
|
/// <param name="propagation">事件传播方式</param>
|
||||||
public void Send<T>(T e, EventPropagation propagation)
|
public void Send<T>(T e, EventPropagation propagation)
|
||||||
{
|
{
|
||||||
|
_statistics?.RecordPublish(typeof(T).Name);
|
||||||
|
|
||||||
_mPriorityEvents
|
_mPriorityEvents
|
||||||
.GetOrAddEvent<PriorityEvent<T>>()
|
.GetOrAddEvent<PriorityEvent<T>>()
|
||||||
.Trigger(e, propagation);
|
.Trigger(e, propagation);
|
||||||
@ -75,6 +81,32 @@ public sealed class EnhancedEventBus : IEventBus
|
|||||||
/// <returns>反注册接口,用于取消订阅</returns>
|
/// <returns>反注册接口,用于取消订阅</returns>
|
||||||
public IUnRegister Register<T>(Action<T> onEvent)
|
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);
|
return _mEvents.GetOrAddEvent<Event<T>>().Register(onEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,6 +119,32 @@ public sealed class EnhancedEventBus : IEventBus
|
|||||||
/// <returns>反注册接口,用于取消订阅</returns>
|
/// <returns>反注册接口,用于取消订阅</returns>
|
||||||
public IUnRegister Register<T>(Action<T> onEvent, int priority)
|
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);
|
return _mPriorityEvents.GetOrAddEvent<PriorityEvent<T>>().Register(onEvent, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,6 +156,7 @@ public sealed class EnhancedEventBus : IEventBus
|
|||||||
public void UnRegister<T>(Action<T> onEvent)
|
public void UnRegister<T>(Action<T> onEvent)
|
||||||
{
|
{
|
||||||
_mEvents.GetEvent<Event<T>>().UnRegister(onEvent);
|
_mEvents.GetEvent<Event<T>>().UnRegister(onEvent);
|
||||||
|
UpdateEventListenerCount<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -108,6 +167,32 @@ public sealed class EnhancedEventBus : IEventBus
|
|||||||
/// <returns>反注册接口,用于取消订阅</returns>
|
/// <returns>反注册接口,用于取消订阅</returns>
|
||||||
public IUnRegister RegisterWithContext<T>(Action<EventContext<T>> onEvent)
|
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);
|
return _mPriorityEvents.GetOrAddEvent<PriorityEvent<T>>().RegisterWithContext(onEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,6 +205,33 @@ public sealed class EnhancedEventBus : IEventBus
|
|||||||
/// <returns>反注册接口,用于取消订阅</returns>
|
/// <returns>反注册接口,用于取消订阅</returns>
|
||||||
public IUnRegister RegisterWithContext<T>(Action<EventContext<T>> onEvent, int priority)
|
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);
|
return _mPriorityEvents.GetOrAddEvent<PriorityEvent<T>>().RegisterWithContext(onEvent, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,4 +351,40 @@ public sealed class EnhancedEventBus : IEventBus
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#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
|
||||||
}
|
}
|
||||||
@ -12,8 +12,6 @@ public sealed class EventStatistics : IEventStatistics
|
|||||||
private readonly Dictionary<string, int> _listenerCountByType = new();
|
private readonly Dictionary<string, int> _listenerCountByType = new();
|
||||||
private readonly object _lock = new();
|
private readonly object _lock = new();
|
||||||
private readonly Dictionary<string, long> _publishCountByType = new();
|
private readonly Dictionary<string, long> _publishCountByType = new();
|
||||||
private int _activeEventTypes;
|
|
||||||
private int _activeListeners;
|
|
||||||
private long _totalFailed;
|
private long _totalFailed;
|
||||||
private long _totalHandled;
|
private long _totalHandled;
|
||||||
private long _totalPublished;
|
private long _totalPublished;
|
||||||
@ -30,15 +28,25 @@ public sealed class EventStatistics : IEventStatistics
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public int ActiveEventTypes
|
public int ActiveEventTypes
|
||||||
{
|
{
|
||||||
get => Interlocked.CompareExchange(ref _activeEventTypes, 0, 0);
|
get
|
||||||
set => Interlocked.Exchange(ref _activeEventTypes, value);
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
return _publishCountByType.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public int ActiveListeners
|
public int ActiveListeners
|
||||||
{
|
{
|
||||||
get => Interlocked.CompareExchange(ref _activeListeners, 0, 0);
|
get
|
||||||
set => Interlocked.Exchange(ref _activeListeners, value);
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
return _listenerCountByType.Values.Sum();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -65,8 +73,6 @@ public sealed class EventStatistics : IEventStatistics
|
|||||||
Interlocked.Exchange(ref _totalPublished, 0);
|
Interlocked.Exchange(ref _totalPublished, 0);
|
||||||
Interlocked.Exchange(ref _totalHandled, 0);
|
Interlocked.Exchange(ref _totalHandled, 0);
|
||||||
Interlocked.Exchange(ref _totalFailed, 0);
|
Interlocked.Exchange(ref _totalFailed, 0);
|
||||||
Interlocked.Exchange(ref _activeEventTypes, 0);
|
|
||||||
Interlocked.Exchange(ref _activeListeners, 0);
|
|
||||||
|
|
||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -61,21 +61,21 @@ public sealed class FilterableEvent<T>
|
|||||||
// 记录发布统计
|
// 记录发布统计
|
||||||
_statistics?.RecordPublish(typeof(T).Name);
|
_statistics?.RecordPublish(typeof(T).Name);
|
||||||
|
|
||||||
// 应用过滤器
|
// 在单个锁中快照过滤器和监听器
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
// 事件被过滤,不触发监听器
|
|
||||||
if (_filters.Any(filter => filter.ShouldFilter(data)))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取当前监听器快照(在锁外调用)
|
|
||||||
Action<T>? handlers;
|
Action<T>? handlers;
|
||||||
|
IEventFilter<T>[] filtersSnapshot;
|
||||||
|
|
||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
|
filtersSnapshot = _filters.Count > 0 ? _filters.ToArray() : Array.Empty<IEventFilter<T>>();
|
||||||
handlers = _onEvent;
|
handlers = _onEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 在锁外执行过滤逻辑
|
||||||
|
// 事件被过滤,不触发监听器
|
||||||
|
if (filtersSnapshot.Any(filter => filter.ShouldFilter(data)))
|
||||||
|
return;
|
||||||
|
|
||||||
if (handlers == null)
|
if (handlers == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@ -254,6 +254,15 @@ public class PriorityEvent<T> : IEvent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前已注册的监听器总数量(包括普通监听器和上下文监听器)
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>监听器总数量</returns>
|
||||||
|
public int GetListenerCount()
|
||||||
|
{
|
||||||
|
return _handlers.Count + _contextHandlers.Count;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 事件处理器包装类,包含处理器和优先级
|
/// 事件处理器包装类,包含处理器和优先级
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
108
GFramework.Core/events/StatisticsEventDecorator.cs
Normal file
108
GFramework.Core/events/StatisticsEventDecorator.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user