mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +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);
|
||||
}
|
||||
|
||||
/// <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;
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -254,6 +254,15 @@ public class PriorityEvent<T> : IEvent
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前已注册的监听器总数量(包括普通监听器和上下文监听器)
|
||||
/// </summary>
|
||||
/// <returns>监听器总数量</returns>
|
||||
public int GetListenerCount()
|
||||
{
|
||||
return _handlers.Count + _contextHandlers.Count;
|
||||
}
|
||||
|
||||
/// <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