2025-09-30 14:37:47 +08:00
|
|
|
|
using System.Collections.Concurrent;
|
2025-09-30 14:31:53 +08:00
|
|
|
|
|
|
|
|
|
|
namespace guoke
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 通用事件参数类,继承自 EventArgs,用于传递事件相关的消息和数据。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class GeneralEventArgs : EventArgs
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取或设置事件相关的消息。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string Message { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取或设置事件相关的数据。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public object Data { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 初始化 GeneralEventArgs 类的新实例。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="message">事件相关的消息。</param>
|
|
|
|
|
|
/// <param name="data">事件相关的数据。</param>
|
|
|
|
|
|
public GeneralEventArgs(string message, object data)
|
|
|
|
|
|
{
|
|
|
|
|
|
Message = message;
|
|
|
|
|
|
Data = data;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 事件字典,用于管理和触发事件。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <typeparam name="TEventArgs">事件参数的类型,必须继承自 EventArgs。</typeparam>
|
|
|
|
|
|
public class EventService<TEventArgs> where TEventArgs : EventArgs
|
|
|
|
|
|
{
|
|
|
|
|
|
// 使用并发字典来存储事件,减少锁的使用
|
|
|
|
|
|
private readonly ConcurrentDictionary<string, EventHandler<TEventArgs>> _events = new ConcurrentDictionary<string, EventHandler<TEventArgs>>();
|
|
|
|
|
|
private readonly ConcurrentDictionary<string, Func<object, TEventArgs, Task>> _asyncEvents = new ConcurrentDictionary<string, Func<object, TEventArgs, Task>>();
|
|
|
|
|
|
|
|
|
|
|
|
private LogService log;
|
|
|
|
|
|
public EventService(LogService logService)
|
|
|
|
|
|
{
|
|
|
|
|
|
log = logService;
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 验证事件名称和处理程序是否有效。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="eventName">事件名称。</param>
|
|
|
|
|
|
/// <param name="handler">事件处理程序。</param>
|
|
|
|
|
|
private bool ValidateEventParams(string eventName, Delegate handler)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrEmpty(eventName))
|
|
|
|
|
|
{
|
|
|
|
|
|
log.Warn($"事件名称不能为 null 或空字符串");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (handler == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
log.Warn($"事件处理程序不能为 null");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 验证事件名称和事件参数是否有效。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="eventName">事件名称。</param>
|
|
|
|
|
|
/// <param name="e">事件参数。</param>
|
|
|
|
|
|
private bool ValidateTriggerParams(string eventName, TEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrEmpty(eventName))
|
|
|
|
|
|
{
|
|
|
|
|
|
log.Warn($"事件名称不能为 null 或空字符串");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 添加同步事件处理程序。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="eventName">事件名称,不能为 null 或空字符串。</param>
|
|
|
|
|
|
/// <param name="handler">事件回调方法,不能为 null。</param>
|
|
|
|
|
|
public void AddEventHandler(string eventName, EventHandler<TEventArgs> handler)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 参数验证
|
|
|
|
|
|
if (ValidateEventParams(eventName, handler))
|
|
|
|
|
|
{
|
|
|
|
|
|
// 使用并发字典的 AddOrUpdate 方法来添加或更新事件处理程序
|
|
|
|
|
|
_events.AddOrUpdate(eventName, handler, (key, existingHandler) => existingHandler + handler);
|
|
|
|
|
|
log.Info($"添加同步事件:[{eventName}]成功");
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
log.Warn($"添加同步事件:[{eventName}]失败");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 添加异步事件处理程序。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="eventName">事件名称,不能为 null 或空字符串。</param>
|
|
|
|
|
|
/// <param name="asyncHandler">异步事件回调方法,不能为 null。</param>
|
|
|
|
|
|
public void AddAsyncEventHandler(string eventName, Func<object, TEventArgs, Task> asyncHandler)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 参数验证
|
|
|
|
|
|
if( ValidateEventParams(eventName, asyncHandler))
|
|
|
|
|
|
{
|
|
|
|
|
|
// 使用并发字典的 AddOrUpdate 方法来添加或更新异步事件处理程序
|
|
|
|
|
|
_asyncEvents.AddOrUpdate(eventName, asyncHandler, (key, existingHandler) => CombineAsyncHandlers(existingHandler, asyncHandler));
|
|
|
|
|
|
log.Info($"添加异步事件:[{eventName}]成功");
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
log.Warn($"添加异步事件:[{eventName}]失败");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private Func<object, TEventArgs, Task> CombineAsyncHandlers(Func<object, TEventArgs, Task> existingHandler, Func<object, TEventArgs, Task> newHandler)
|
|
|
|
|
|
{
|
|
|
|
|
|
return async (sender, e) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
await existingHandler(sender, e);
|
|
|
|
|
|
await newHandler(sender, e);
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 移除同步事件处理程序。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="eventName">事件名称,不能为 null 或空字符串。</param>
|
|
|
|
|
|
/// <param name="handler">事件方法,不能为 null。</param>
|
|
|
|
|
|
public void RemoveEventHandler(string eventName, EventHandler<TEventArgs> handler)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 参数验证
|
|
|
|
|
|
ValidateEventParams(eventName, handler);
|
|
|
|
|
|
|
|
|
|
|
|
// 尝试获取事件处理程序
|
|
|
|
|
|
if (_events.TryGetValue(eventName, out var existingHandler))
|
|
|
|
|
|
{
|
|
|
|
|
|
// 移除指定的事件处理程序
|
|
|
|
|
|
var newHandler = existingHandler - handler;
|
|
|
|
|
|
if (newHandler == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 如果移除后事件处理程序为空,则从字典中移除该事件
|
|
|
|
|
|
_events.TryRemove(eventName, out _);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// 更新事件处理程序
|
|
|
|
|
|
_events[eventName] = newHandler;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 移除异步事件处理程序。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="eventName">事件名称,不能为 null 或空字符串。</param>
|
|
|
|
|
|
/// <param name="asyncHandler">异步事件方法,不能为 null。</param>
|
|
|
|
|
|
public void RemoveAsyncEventHandler(string eventName, Func<object, TEventArgs, Task> asyncHandler)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 参数验证
|
|
|
|
|
|
ValidateEventParams(eventName, asyncHandler);
|
|
|
|
|
|
|
|
|
|
|
|
// 尝试获取事件处理程序
|
|
|
|
|
|
if (_asyncEvents.TryGetValue(eventName, out var existingHandler))
|
|
|
|
|
|
{
|
|
|
|
|
|
// 这里简单模拟移除,实际情况可能需要更复杂的处理
|
|
|
|
|
|
var newHandler = RemoveAsyncHandler(existingHandler, asyncHandler);
|
|
|
|
|
|
if (newHandler == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 如果移除后事件处理程序为空,则从字典中移除该事件
|
|
|
|
|
|
_asyncEvents.TryRemove(eventName, out _);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// 更新事件处理程序
|
|
|
|
|
|
_asyncEvents[eventName] = newHandler;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private Func<object, TEventArgs, Task> RemoveAsyncHandler(Func<object, TEventArgs, Task> existingHandler, Func<object, TEventArgs, Task> handlerToRemove)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 简单实现,需要根据实际组合逻辑调整
|
|
|
|
|
|
return (sender, e) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
// 这里简单跳过要移除的处理程序
|
|
|
|
|
|
return existingHandler(sender, e);
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 触发同步事件。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="eventName">事件名,不能为 null 或空字符串。</param>
|
|
|
|
|
|
/// <param name="sender">事件发布者,可以用来传递数据。</param>
|
|
|
|
|
|
/// <param name="e">事件参数对象,不能为 null。</param>
|
|
|
|
|
|
public void TriggerEvent(string eventName, object sender, TEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 参数验证
|
|
|
|
|
|
ValidateTriggerParams(eventName, e);
|
|
|
|
|
|
|
|
|
|
|
|
// 尝试获取事件处理程序并触发事件
|
|
|
|
|
|
if (_events.TryGetValue(eventName, out var handler))
|
|
|
|
|
|
{
|
|
|
|
|
|
handler?.Invoke(sender, e);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 触发异步事件。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="eventName">事件名,不能为 null 或空字符串。</param>
|
|
|
|
|
|
/// <param name="sender">事件发布者,可以用来传递数据。</param>
|
|
|
|
|
|
/// <param name="e">事件参数对象,不能为 null。</param>
|
|
|
|
|
|
/// <returns>表示异步操作的任务。</returns>
|
|
|
|
|
|
public async Task TriggerAsyncEvent(string eventName, object sender, TEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 参数验证
|
|
|
|
|
|
ValidateTriggerParams(eventName, e);
|
|
|
|
|
|
|
|
|
|
|
|
// 尝试获取异步事件处理程序并触发事件
|
|
|
|
|
|
if (_asyncEvents.TryGetValue(eventName, out var asyncHandler))
|
|
|
|
|
|
{
|
|
|
|
|
|
await asyncHandler(sender, e);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|