在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
但是,不是我们时刻都需要这样申明的,因为它会适当占用我们的内存空间。这时我们可以采用另一种基于键值对的方式来操作,需要的时候在创建和调用,不需要的时候就移出。即:通过add和remove访问器来自定义实现添加和移出事件处理程序。 下面说说实现该方案的整个流程: 1:声明事件类型 eg: public delegate void DemoEventHandler(object sender,yourEventArgs e); 2: 为事件生成一个唯一的键 eg: static readonly object DemoEventKey = new object(); 3: 使用Hashtable 存储事件处理程序 eg: protected Hashtable handlers = new Hashtable(); 4: 写入事件 add / remove 访问器 eg: public void AddEventHandler(object eventKey, Delegate handler) { lock(this) { if (handlers[ eventKey ] == null) { handlers.Add( eventKey, handler ); } else { handlers[ eventKey ] = handler; } } } public void RemoveEventHandler(object eventKey) { lock(this) { handlers.Remove( eventKey ); } } public Delegate GetEventHandler(object eventKey) { return (Delegate) handlers[ eventKey ]; } 5:进行事件申明 eg: public event DemoEventHandler Demo { add { AddEventHandler(DemoEventKey, value); } remove { RemoveEventHandler(DemoEventKey); } } 6:对事件进行包装 eg: //DemoEventArgs应该是从System.EventArgs而来 public virtual void OnDemo(DemoEventArgs e ) { DemoEventHandler handler = (DemoEventHandler) GetEventHandler( DemoEventKey ); if (handler != null) { handler(this, e); } } 7:使用事件 eg: public void DoSomething() { //此处需要看具体情况向外界发出对应的事件参数 //通常可以采用构造函数完成。 OnDemo(new DemoEventKey(yourParameter)) } 8://连接事件进处理,和一般的事件处理程序一样进行挂接 略 BTW: 事实上对于上面的方案,如果该事件被挂接多次的话,后面事件处理程序会覆盖前面的,也就是说最终只有一个事件被真正的挂接,这也就是所谓的单播事件.当然为了解决这个问题我们可以采用多播事件来处理,如果知道Observer模式的同志就不会陌生了.一般可以按照传统采用非静态成员来标识事件类型的方式,当在客户端为一个事件预定多个事件处理函数的时候,是按照队列的方式来处理的(即先进先出原则),比如ListDictionary是个选择,不过当事件很多而对性能要求又很高时,需考虑其它方式实现了. |
请发表评论