事件管理
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();
好理解都加了注释!
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();
好理解都加了注释!
相关文章推荐
- C# 常用代码
- BZOJ 2395 Time is Money
- Java分布式优化
- 简单的用ApplicationContext做测试的话,获得Spring中定义的Bean实例
- WCF编程系列:地址与绑定
- 文章标题
- Intel 82599 ixgbe & ixgbevf CNA 卡驱动分析02——VF/PF/MailBox
- 写博客的时间被看小说、刷微信的时候,要想想
- memcached杂记
- .htaccess Apache服务器中的一个配置文件,它负责相关目录下的网页配置
- 数据库中父表和子表(主键外键的理解)
- 需求分析、概要设计、详细设计析义(转)
- linux遍历目录及其子目录
- Intel 82599 ixgbe & ixgbevf CNA 卡驱动分析01——SR-IOV
- Resin 在同一台机器不同端口启动两个应用
- C#临门一脚
- Leet Code OJ 219. Contains Duplicate II [Difficulty: Easy]
- 【Xamarin挖墙脚系列:应用的性能调优】
- jQuery响应式幻灯片插件jquery.glide.js(支持触摸&轻量级)
- JMeter的基本介绍和入门