《C#和.Net核心技术》
委托和实践
点击提交按钮、在窗体内移动鼠标、按下回车键、在I/O端口接收一个字符,这些都是事件(event),他们常常触发程序中一个或多个特殊事件处理例程(event handling routine)调用.
在 .NET中,事件实际上是类成员,与其他成员属性方法一样,FCL中几乎每个类都有事件成员。Control类就是一个很好的例子,它是所有GUI组件的基类。它的事件(包括Click、DoubleClick、KeyUp和 GotFocus)设计成可以识别用户与应用交互时最常见的动作。但事件之是一方面,另一方面是响应或处理事件的方法,因此,如果查看Control类方法,可以看到OnClick、OnDoubleClick、OnKeyUp以及其他事件处理方法
事件与事件处理程序之间的基本关系,这种关系称为发布者/订购者(publisher/subscriber)模式,发出事件的对象称为发布者,而处理事件的方法则为订购者.
1.委托
将事件与处理方法关联起来的 是委托对象(delegate object)。该对象维护着事件发生时调用方法的方法列表.其角色类似于Windows API程序员熟悉的回调函数,但它在代码安全性上有相当大的改善
在MicrosoftWindows编程冲,当一个函数使用受到的函数指针来调用另一个函数时,就会发生回调。调用函数无法知道指针是否指向另一个有效函数,起结果常常是由于不正确的内存引用而导致程序错误,甚至崩溃。.Net的委托则消除了这个问题.C#编译器会完成类型检查,一确保委托只调用“正确的”方法,即方法的签名和返回类型要与委托生命中指定的签名和返回类型匹配,作为一个实例.开率以下委托声名:
public delegate void MyString(string msg);
声明委托时,C#编译器会创建一个sealed(密封)类,并以委托标识符(MyString命名).该类定义了一个构造函数,它接收方法(可以是静态方法或实例方法)名做为其一个参数,该类还包含另外一些方法,以支持委托维护目标方法列表。这以为着,不同于回调方法,一个委托可以调用多个时间处理方法
方法必须向委托注册,以便委托能调用这个方法。只有无返回值而且接受一个字符串参数的方法才能向这个委托注册,否则,将出现编译错误。下面代码展示了如何声明MyString委托,并向这个委托注册多个方法,调用委托时,它会遍历所有内部调用列表,并按照方法注册顺序调用所有注册方法。调用多个方法的过程称为组播(multicasting)
注意:+=操作符用于向调用列表增加方法。相反的,可以使用-=操作符从中删除方法
(创建委托实例,绑定委托方法,调用委托 )
前面的示例中,委托同步地调用每个方法,这说明,只有前一个方法完成操作,才会调用后面的方法。这可能存在来个问题:某个方法可能被"挂起",永远不返回控制,或者需要很长的时间来完成处理。他们将阻塞整个应用,为了解决这个问题,.NET允许委托对方执行异步调用。在这种情况下,被调用的方法与调用方法将在不同的现成中运行,这样一来,调用方法能通过轮询来确定被调用的方法与调用方法将在不同的线程中运行,这样一来,调用方法能拖国轮询来确定被调用方法何时结束,或者让被调用方法在完成是回调一个方法.
2.基于委托的事件处理
抽象的讲,.NET模型基于观察者模式(ObserverDesignPattern).这个模式定义为"对象间存在一对多依赖关系,一个对象改变状态时,以来于此的所有对象都能得到同志并自动更新".事件发生时,所有委托的注册方法都能收到通知并自动执行“。要想正确的处理.NET中的事件,关键是要理解时间和委托是如何工作的。
处理内置事件
下列代码的实力将显示一个窗体,你可以拖动鼠标在窗体上画线,(按下鼠标键,移动鼠标至合适位置,送开鼠标键).要想得到线的端点,必须能识别MouseDown和MNouseUp事件.MouseUp实际那发生时,就要画上线.
MouseEventHandler委托和MouseDown时间都是FLCD中预定义的,这就减轻了开发人员的工作,只需要实现吃件处理程序,并向委托注册既可,+=操作符用于注册与事件相关的方法.
this.MouseDown += new MouseEventHandler(OnMouseDown);
该语句的基本结构是:
this.event += new delegate(event handler methos);
要实现事件处理程序,必须提供委托定义签名,在描述MouseEventHandler委托生命的文档中可以找到该签名,
public delegate void MouseEventHandler(object sender,MouseEventArgs e)
浙公网安备 33010602011771号