.NET事件机制

一,    事件及事件驱动

1,事件的概念

软件事件是对现实生活中的事件的模拟。从面向对象的角度来说,事件是由对象发出的消息,它是一个信号,通知其他对象有事情发生。例如,单击窗体上的某个控件时,控件可能会激发一个Click事件。

激发与相应事件的载体都是对象。激发事件的对象被称为“事件源”,对这个事件进行响应的对象称为“响应者” 响应者必须提供一个“事件响应(或处理)方法”。

2,事件与多路委托

       事件的主要特点是一对多的关联,即一个事件源可以有多个响应者。在具体实现上,.NET Framework的事件处理机制是基于多路委托实现的。

先看一个使用多路委托实现事件的实例项目代码如下:

public delegate void MyEventDelegate(int value);

接着定义了EventSource(事件源)EventResponsor(事件响应源)两个类,注意EventSource类中有一个MyEverntDelegate类型的字段,它将用于引用事件相应的方法。

   public delegate void MyEventDelegate(int value);

    public class EventSource

    {

        public MyEventDelegate handlers;//事件响应者清单

    }

    public class EventResponsor

    {

        public void MyMethod(int i)//事件响应方法

        {

            Console.WriteLine(i);

        }

    }

以下为模板实现事件的响应代码,请注意多个事件响应方法挂接到多路委托变量上的几种方式:

   class Class1

    {

        static void Main()

        {

            //一个事件源对象

            EventSource p = new EventSource();

            //创建两个响应者

            EventResponsor Responsor1 = new EventResponsor();

            EventResponsor Responsor2 = new EventResponsor();

            //课连续调用Delegate类的静态方法组合多个委托变量

            p.handlers = System.Delegate.Combine(p.handlers, new MyEventDelegate(Responsor1.MyMethod)) as MyEventDelegate;

            p.handlers = System.Delegate.Combine(p.handlers, new MyEventDelegate(Responsor2.MyMethod)) as MyEventDelegate;

            //或调用+=运算组合委托变量

            //p.handlers += new MyEventDelegate(Responsor1.MyMethod);

            //p.handlers += new MyEventDelegate(Responsor2.MyMethod);

            //最简单的写法

            //p.handlers+=Responsor1.MyMethod;

            //p.handlers+=Responsor2.MyMethod;

           

            //直接调用委托变量,代表激发事件

            p.handlers(10);

        }

    }

上述代码执行到最后一句的时候,将会调用两个事件响应者Responsor1Responsor2的事件响应方法MyMtthod,在控制台输出两个整数:

10  

10

上面这个例子中,事件的激发是在Main方法中引发的(也即上述代码的最后一句),而真实的事件不应该允许有外界引发,必须有事件源对象自己引发。

       为了限制事件的激发只能由事件源对象自己引发,C#引入了一个新的关键字——event。为此需要修改前面例子中的EventSource

       public class EventSource

    {

        public event  MyEventDelegate handlers;//定义一个事件

        public void FireEvent()

        {

            if (handlers != null)//如果有响应者

                handlers(10);//激发事件

        }

    }

与前面不同之处在于EventSource类给handlers字段增加了一个event关键字,并提供了一个新的用于激发事件的方法FireEvent

以下为模拟实现事件响应的代码:

class Class1

    {

        static void Main()

        {

            //一个事件源对象

            EventSource p = new EventSource();

            //创建两个事件响应者

            EventResponsor Responsor1 = new EventResponsor();

            EventResponsor Responsor2 = new EventResponsor();     

            //必须使用+=运算给事件追加委托

            p.handlers += new MyEventDelegate(Responsor1.MyMethod);

            p.handlers += new MyEventDelegate(Responsor2.MyMethod);

//声明为事件的委托不能直接调用,下面的这句不能通过编译

//p.handlers(10);这能通过累的公有方法间接的引发事件

            p.FireEvent();

        }

    }

       请注意上述代码只能使用“+=”给handles事件追加委托,也只能通过类的静态公有方法间接地激发此事件。

       对比以上的两个实例,不难看出事件的这两种实现方法大同小异,本质上是一回事,只不过后面的使用多路委托是允许外界直接引发事件罢了

3,。NET事件实现机制剖析

posted @ 2011-09-28 18:22  一斤半  阅读(726)  评论(0编辑  收藏  举报