• 事件


          事件的主要特点是一对多关联,即一个事件源,多个响应者。在具体技术上,     .NET

    Framework的事件处理机制是基于多路委托实现的。

    8.1事件与多路委托

          先看一个多路委托示例项目  MulticastDelegateLinkExample。

    首先定义一个委托:

    public delegate void MyMultiDelegate(int value );

    接着,定义事件发布者与响应者类:

    //事件发布者类

    public class  Publisher

    {

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

    }

    //事件响应者类

    public class Subscriber

    {

         //事件处理函数

         public void MyMethod(int i)

       {

             Console.WriteLine(i);

       }

    }

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

    static void Main(string[] args)

    {

        //一个事件源对象

        Publisher p = new  Publisher();

          //两个事件响应者

         Subscriber s1 = new  Subscriber();

         Subscriber s2 = new  Subscriber();

          //可以直接调用Delegate类的静态方法组合多个委托

          p.handl ers = System.Delegate.Combine(p.handlers,  new

                   MyMultiDelegate(s1.MyMethod)) as  MyMultiDelegate;

          p.handl ers = System.Delegate.Combine(p.handlers,  new

                   MyMultiDelegate(s2.MyMethod)) as  MyMultiDelegate;

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

        //p.handlers += new MyMultiDelegate(s1.MyMethod);

        //p.handlers += new MyMultiDelegate(s2.MyMethod);

        //最简单的写法

        //p.handlers += s1.MyMethod;

        //p.handlers += s2.MyMethod;

     

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

       p.handlers(10);

     }

          上述代码执行到最后一句时,将会调用两个事件响应者       s1和    s2的事件响应函数

    MyMethod,在控制台窗口输出两个整数:

          10

          10

          上面这个例子中,事件的激发是在 Main()函数中引发的(即上述代码的最后一句),而

    真实的事件不应允许由外界引发,必须由事件源对象自己引发。

          为了限制事件的激发只能由事件源对象自己引发,C#引入了一个新的关键字——event,

    为此需要修改 UseMultiDelegateExample项目(参看项目  UseEventExample):

    public delegate void MyMultiDelegate(int  value);

    //事件发布者类

    public class  Publisher

    {

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

       //激发事件

        public void FireEvent()

      {

          handlers(10);

      }

    }

     

     //事件响应者类

    public class  Subscriber

    {

         //事件处理函数

         public void MyMethod(int i)

      {

         Console.WriteLine(i);

      }

     }

          与前不同之处在于 Publisher类给  handlers字段增加了一个  event关键字,并提供了一个

    新的用于激发事件的方法 FireEvent()。

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

    static void Main(string[] args)

    {

           Publisher p = new  Publisher();

           Subscriber s1 = new  Subscriber();

           Subscriber s2 = new  Subscriber();

          //声明为事件的委托无法直接调用Combine方法

           //以下两句将无法通过编译

          //p.handl ers = System.Delegate.Combine(p.handlers,

                     new MyMultiDelegate(s1.MyMethod)) as MyMultiDelegate;

           //p.handl ers = System.Delegate.Combine(p.handlers,

                     new MyMultiDelegate(s2.MyMethod)) as MyMultiDelegate;

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

          p.handlers+=new  MyMultiDelegate(s1.MyMethod);

          p.handlers+=new  MyMultiDelegate(s2.MyMethod);

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

          //p.handlers(10);

          //只能通过类的公有方法间接地引发事件

           p.FireEvent();

    }

          请注意上述代码中被注释掉的代码,它们是无法通过编译的,只能使用+=给  handles

    事件追加委托,也只能通过类的公有方法来间接地激发此事件。

          对比以上两个示例,不难看出事件与多路委托其实大同小异,只不过多路委托允许在

    事件源对象之外激发事件罢了。

    事件小结

          面向对象的软件系统有许多都是事件驱动的,比如 ASP.NET就采用了事件驱动

    编程方式。

          所谓事件驱动的开发方式,就是指整个系统包含许多的对象,这些对象可以引发多

    种事件,软件工程师的主要开发工作就是针对特定的事件书写代码响应它们。

          .NET事件处理机制建立在委托的基础之上,而这两者都是  ASP.NET技术的基础之一。

    因此,必须牢固地掌握好委托和事件这两种编程技术,才能为掌握 ASP.NET技术扫清障碍。

  • 相关阅读:
    使用MFC界面库LibUIDK制作超酷界面
    使用WSH和WMI实现定时记录系统CPU和内存使用率
    关于CreateFileMapping的问题
    360对NSIS误报Malware.QVM06.GEN的解决办法
    win2003实现单用户远程登录
    All bytes must be within the maximum size specified by CreateFileMapping
    解决在VS2005中“当前不会命中断点。源代码与原始版本不同”的问题
    static library中能不能带资源
    HUDSON_HOME
    USB GUID查找
  • 原文地址:https://www.cnblogs.com/LCL390/p/4301244.html
Copyright © 2020-2023  润新知