您的位置:首页 > 其它

委托和事件的一个例子解读From msdn of Microsoft

2010-01-21 18:30 309 查看
这是msdn上的一个事件和委托的例子。比较适合初步了解事件和委托的关系和实现

本博客还有一个更好的讲解事件和委托的文章,那个更高级,更全面。

----》点击链接 本博客的其他文章委托和事件

或对象可以通过事件向其他类或对象通知发生的相关事情。发送(或引发)事件的类称为“发行者”,接收(或处理)事件的类称为“订户”。

在典型的 C# Windows 窗体或 Web 应用程序中,可订阅由控件(如按钮和列表框)引发的事件。可使用 Visual C# 集成开发环境 (IDE) 来浏览控件发布的事件,选择要处理的事件。IDE 会自动添加空事件处理程序方法和订阅事件的代码。0 && image.height>0){if(image.width>=700){this.width=700;this.height=image.height*700/image.width;}}" style="BORDER-RIGHT-WIDTH: 0px; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; VERTICAL-ALIGN: middle; BORDER-LEFT-WIDTH: 0px" class=LibC_o src="http://i.msdn.microsoft.com/Global/Images/clear.gif" jQuery1264041402578="2"> 事件概述

事件具有以下特点:

发行者确定何时引发事件,订户确定执行何种操作来响应该事件。

一个事件可以有多个订户。一个订户可处理来自多个发行者的多个事件。

没有订户的事件永远也不会引发。

事件通常用于通知用户操作,例如,图形用户界面中的按钮单击或菜单选择操作。

如果一个事件有多个订户,当引发该事件时,会同步调用多个事件处理程序。可以利用事件同步线程。

在 .NET Framework 类库中,事件是基于 EventHandler 委托和 EventArgs 基类的。

首先应该这样理解事件。事件模式中存在事件发布者和事件订阅者,发布者引发事件,并且通知该事件的订阅者;订阅者知道事件已经触发以后去调用自己相关的事件处理方法。一个事件发布者可以有多个订阅者,一个事件订阅者也可以订阅多个事件发布者;事件发布者仅仅引发,触发事件,至于订阅者怎么处理,响应这些事件都是由订阅者自己来定义和处理的。

这个列子演示如何将符合标准 .NET Framework 模式的事件添加到您自己的类和结构中。.NET Framework 类库中的所有事件均基于 EventHandler 委托,定义如下: //基于委托模式的事件定义,两个输入参数都是net的标准模式,一个object事件触发者,eventargs事件传递的某些参数,可以自己定义这个参数public delegate void EventHandler(object sender, EventArgs e);

public event EventHandler RaiseCustomEvent;//事件的定义

/*

以下是全部。实例代码,

*/

//这个是事件传递的某些参数,可以自己定义要传递什么数据,但是必须继承EventArgs对象

public class CustomEventArgs : EventArgs
{
public CustomEventArgs(string s)
{
message = s;
}
private string message;

public string Message
{
get { return message; }
set { message = value; }
}
}

//定义委托事件。注意其中的两个输入参数。虽然不是强制规定,但这是net标准模式

public delegate void CustomEventHander(object o,CustomEventArgs args);
//事件的发布者
class Publisher
{

// 声明事件,事件类型急速委托方法的名字。

public event CustomEventHander RaiseCustomEvent;
//事件必须是由发布者引发的,所以发布者必须做某些事情才能引发事件并通知订阅者。这个方法就是事件发布者 要 做的
public void DoSomething()
{
OnRaiseCustomEvent(new CustomEventArgs("Did something"));
}
//封装这个引发事件方法,使用protected和virtual可以一定程度上保护这个方法,并使用继承类可以重写这个方法
protected virtual void OnRaiseCustomEvent(CustomEventArgs e)
{
// 这个地方用了RaiseCustomEvent的临时copy,在竞争条件下如果最后一个订阅者没有立即订阅事件这个对象就是null。
CustomEventHander handler = RaiseCustomEvent;//大家可能注意到这个RaiseCustomEvent也没有实例化,只有一个声明而已。其实这个发布者的RaiseCustomEvent的实例化是在订阅者中实现的。

// 先检查这个事件是否有订阅者
if (handler != null)
{
//事件传递参数的组织
e.Message += String.Format(" at {0}", DateTime.Now.ToString());

// 引发事件
handler(this, e);
}
}
}

//事件订阅者

public class Subscriber
{
private string id;

public Subscriber(string id, PublisherEventTest publisher)
{
this.id = id;

//发布者的RaiseCustomEvent 其实是在这个地方菜实例化的。
//这个事件使用订阅者的那个处理方法,由订阅者选择和实现。就是HandleCustomEvent方法了
publisher.RaiseCustomEvent +=new CustomEventHander(this.HandleCustomEvent );

}

void HandleCustomEvent(object sender, CustomEventArgs e)
{
Console.WriteLine(id + " received this message: {0}", e.MSG);
}

}

//最后客户端的实现

Publisher publisher = new Publisher();//发布者
Subscriber s1 = new Subscriber("1", publisher);//订阅者1
Subscriber s2 = new Subscriber("2", publisher);//订阅者2

publisher.DoSomeThing();//发布者引发了事件,并且通知了订阅者,订阅者去分别指向自己的事件响应方法

输出

1 received this message: do somethings2010-1-21 11:00:54
2 received this message: do somethings2010-1-21 11:00:54

本文使用Blog_Backup未注册版本导出,请到soft.pt42.com注册。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: