您的位置:首页 > 其它

事件管理

2016-03-07 14:13 155 查看
分享一个事件管理的代码:

public static class EventCenter
{
public delegate void callBack<T>(T arg);//定义泛型委托
private static Dictionary<ArgEnum, Delegate> deMap = new Dictionary<ArgEnum, Delegate>();//用于存储事件的列表
private static object locker = new object();//锁的对象
/// <summary>
/// 添加事件
/// </summary>
/// <param name="arg"></param>
/// <param name="handler"></param>
public static void AddListener(ArgEnum arg, callBack<System.Object> handler)
{
lock (locker)//这个要加个锁,防止多线程状况下所造成的资源争夺现象,如果多线程中访问次函数,则出现死锁(等待),直到该锁被释放(locker一定要是引用类型,如果是值类型,将导致每次lock的时候都会将该对象装箱为一个新的引用对象)
{
if (!deMap.ContainsKey(arg))
{
deMap[arg] = null;
}
deMap[arg] = (callBack<System.Object> )deMap[arg] + handler;//将新添加的事件回调方法加入事件列表并加入委托链
}
}
/// <summary>
/// 移除事件
/// </summary>
/// <param name="ae"></param>
/// <param name="handler"></param>
public static void RemoListener(ArgEnum ae,callBack<System.Object> handler)
{
lock (locker)
{
if (deMap.ContainsKey(ae))
{
deMap[ae] = (callBack<System.Object>)deMap[ae] - handler;//将事件回调方法 从所在的委托链中删除
if (deMap[ae] == null) {//如果事件列表中所对应的事件为null也代表所对应事件的委托链为null则移除
deMap.Remove(ae);
}
}
}
}
/// <summary>
/// 触发事件
/// </summary>
/// <param name="ae"></param>
/// <param name="obj"></param>
public static void Invoke(ArgEnum ae, System.Object obj)
{
lock (locker)
{
Delegate key;
if (deMap.TryGetValue(ae, out key))
{
if (key != null)
{
callBack<System.Object> cb = key as callBack<System.Object>;//将对应的事件强制转换为callBack<System.Object>
cb(obj);//触发事件
}
}
else
{
throw new NullReferenceException("未注册此事件" + ae);//抛出空异常
}
}
}
/// <summary>
/// 是否包含次事件
/// </summary>
/// <param name="ae"></param>
/// <returns></returns>
public static bool Contains(ArgEnum ae)
{
return deMap.ContainsKey(ae);
}
}
public enum ArgEnum
{
TEST1,
TEST2,
TEST3
}

使用

EventCenter.AddListener(ArgEnum.TEST1, AlertClick);
EventCenter.Invoke(ArgEnum.TEST1,"呵呵");
Console.ReadLine();
EventCenter.AddListener(ArgEnum.TEST1, AlertClick1);
EventCenter.Invoke(ArgEnum.TEST1, "嘿嘿");
Console.ReadLine();
EventCenter.RemoListener(ArgEnum.TEST1, AlertClick);
Console.WriteLine("是否包含" + EventCenter.Contains(ArgEnum.TEST1));
EventCenter.Invoke(ArgEnum.TEST1, "哈哈");
EventCenter.RemoListener(ArgEnum.TEST1, AlertClick1);
Console.WriteLine("是否包含" + EventCenter.Contains(ArgEnum.TEST1));
Console.ReadLine();

好理解都加了注释!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: