委托和事件的一个例子解读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注册。

posted @ 2010-01-21 18:30  音乐啤酒  阅读(288)  评论(0编辑  收藏  举报