http://dev.tot.name/csharp/html/2010029/20100209103147.htm
一、使用事件的好处
在以往我们编写这类程序中,往往采用等待机制,为了等待某件事情的发生,需要不断地检测某些判断变量,而引入事件编程后,大大简化了这种过程:
- 使用事件,可以很方便地确定程序执行顺序。
- 当事件驱动程序等待事件时,它不占用很多资源。事件驱动程序与过程式程序最大的不同就在于,程序不再不停地检查输入设备,而是呆着不动,等待消息的到来,每个输入的消息会被排进队列,等待程序处理它。如果没有消息在等待,则程序会把控制交回给操作系统,以运行其他程序。
- 事件简化了编程。操作系统只是简单地将消息传送给对象,由对象的事件驱动程序确定事件的处理方法。操作系统不必知道程序的内部工作机制,只是需要知道如何与对象进行对话,也就是如何传递消息。 网
二、举例
1、首先创建一个自己的EventArgs类。
引自MSDN:
EventArgs是包含事件数据的类的基类,此类不包含事件数据,在事件引发时不向事件处理程序传递状态信息的事件会使用此类。如果事件处理程序需要状态信息,则应用程序必须从此类派生一个类来保存数据。
因为在我们键盘按键事件中要包含按键信息,所以要派生一个KeyEventArgs类,来保存按键信息,好让后面知道按了哪个键。
//参数封装类
public class KeyEventArgs:EventArgs
{
private char keyChar;
public char KeyChar
{
get { return keyChar; }
set { keyChar = value; }
}
public KeyEventArgs(char keyChar)
{
this.keyChar = keyChar;
}
}
2、 //定义一个委托,可以认为是一个类
public delegate void KeyDown(object sender,KeyEventArgs e);
3、
//事件产生类.监视器,监视用户的输入事件
public class KeyInputMonitor
{
//定义一个事件,将委托和时间关联起来
public event KeyDown OnKeyDown;
public void Run()
{
bool finished = false;
do
{
Console.WriteLine( "Input a char" );
string response = Console.ReadLine();
char responseChar = ( response == "" ) ? ' ' : char.ToUpper( response[0] );
switch( responseChar )
{
case 'X':
finished = true;
break;
default:
// 得到按键信息的参数
KeyEventArgs keyEventArgs = new KeyEventArgs( responseChar );
// 触发事件,并将事件交给KeyDown委托来处理
OnKeyDown( this, keyEventArgs );
break;
}
}while( !finished );
}
}
4、创建一个事件接收方的类,这个类先产生一个委托实例,再把这个委托实例添加到产生事件对象的事件列表中去,这个过程又叫订阅事件。然后提供一个方法回显按键信息。
public class EventReceiver
{
public EventReceiver(KeyInputMonitor monitor)
{
KeyDown newkeydown = new KeyDown(Echo);
monitor.OnKeyDown += new KeyDown(Echo);
}
private void Echo(object sender, KeyEventArgs e)
{
// 真正的事件处理函数
Console.WriteLine("Capture key: {0}", e.KeyChar);
}
}
5、
public class MainEntryPoint
{
public static void start()
{
//生长一个监视器,监视用户的输入操作;
KeyInputMonitor monitor = new KeyInputMonitor();
//事件接受处理类.新产生一个委托,添加到事件列表.这样事件产生时,就会自动调用委托指向的函数.
EventReceiver receiver = new EventReceiver(monitor);
monitor.Run();
}
}
/*
* 可以这样理解委托与事件:
* 一个监视程序,定义了事件发生逻辑.当条件满足时,触发事件处理逻辑; 当然,这时候事件处理逻辑,只是通过委托定义的一个空壳.
* 如果委托没有指向具体的函数,那么就什么也做不了.
*
* 那么事件一旦发生,该如何处理呢? 由事件的事件列表定义. 可以有一个或多个处理函数,
*
* (你可能问,当事件发生条件满足时,直接调用处理函数不就得了,干吗又是事件又是委托呢?原因是,有时候,写事件产生程序的人,是不知道
* 如何处理的,怎么处理,由另外一个人来写.就像VS的界面编程一样,微软的VS开发者写好了点击一个按钮的事件产生程序,他们怎么知道
* 使用VS做开发的怎么定义处理呢?)
* 作者举了一个例子也很好,比如你要租一个房屋,这是一个事件,那么委托就是房屋租赁中介,当你把租房子的消息告知中介后,
* 中介就会产生出一套符合你要求的房屋租赁方案来。再由中介执行这套方案,你便租得了这个房屋,即事件被处理了。
* 当然你也可以不通过中介,直接找房东,但如果没有互联网等工具,你如何得到谁出租房屋的信息?
*
* 事件处理程序,定义了当事件发生时进行的操作.并将该操作通过委托,添加到了事件列表. 事件一旦发生,事件列表中委托定义的所有处理函数,
* 就会一一执行;
*
*
*/
C#中使用事件需要的步骤:
1.创建一个委托
2.将创建的委托与特定事件关联(.Net类库中的很多事件都是已经定制好的,所以他们也就有相应的一个委托,在编写关联事件处理程序--也就是当有事件发生时我们要执行的方法的时候我们需要和这个委托有相同的签名)
3.编写事件处理程序
4.利用编写的事件处理程序生成一个委托实例
5.把这个委托实例添加到产生事件对象的事件列表中去,这个过程又叫订阅事件 中国网管联盟www_bitscn_com
C#中事件产生和实现的流程:
1.定义A为产生事件的实例,a为A产生的一个事件
2.定义B为接收事件的实例,b为处理事件的方法
3.A由于用户(程序编写者或程序使用者)或者系统产生一个a事件(例如点击一个Button,产生一个Click事件)
4.A通过事件列表中的委托对象将这个事件通知给B
5.B接到一个事件通知(实际是B.b利用委托来实现事件的接收)
6.调用B.b方法完成事件处理