委托和事件的一个例子解读From msdn of Microsoft
这是msdn上的一个事件和委托的例子。比较适合初步了解事件和委托的关系和实现
本博客还有一个更好的讲解事件和委托的文章,那个更高级,更全面。
----》点击链接 本博客的其他文章委托和事件
类或对象可以通过事件向其他类或对象通知发生的相关事情。发送(或引发)事件的类称为“发行者”,接收(或处理)事件的类称为“订户”。
在典型的 C# Windows 窗体或 Web 应用程序中,可订阅由控件(如按钮和列表框)引发的事件。可使用 Visual C# 集成开发环境 (IDE) 来浏览控件发布的事件,选择要处理的事件。IDE 会自动添加空事件处理程序方法和订阅事件的代码。 事件概述
事件具有以下特点:
-
发行者确定何时引发事件,订户确定执行何种操作来响应该事件。
-
一个事件可以有多个订户。一个订户可处理来自多个发行者的多个事件。
-
没有订户的事件永远也不会引发。
-
事件通常用于通知用户操作,例如,图形用户界面中的按钮单击或菜单选择操作。
-
如果一个事件有多个订户,当引发该事件时,会同步调用多个事件处理程序。可以利用事件同步线程。
-
在 .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注册。