WpfApp/Services/EventService.cs

231 lines
9.0 KiB
C#
Raw Normal View History

2025-09-30 14:37:47 +08:00
using System.Collections.Concurrent;
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);
}
}
}
}