[技术回顾系列]--c#中事件高级应用

都知道一般情况下事件申明格式如: public event delegate Type event Name;
但是,不是我们时刻都需要这样申明的,因为它会适当占用我们的内存空间。这时我们可以采用另一种基于键值对的方式来操作,需要的时候在创建和调用,不需要的时候就移出。即:通过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是个选择,不过当事件很多而对性能要求又很高时,需考虑其它方式实现了.

posted on 2007-05-10 10:40  kim  阅读(1249)  评论(3编辑  收藏  举报

导航