WpfApp/Services/EventService.cs

231 lines
9.0 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
}
}
}