当前位置: 代码迷 >> C# >> c# 嘱托 事件 EventHandler 观察者模式 详解,以及和java的比较
  详细解决方案

c# 嘱托 事件 EventHandler 观察者模式 详解,以及和java的比较

热度:1361   发布时间:2013-02-25 00:00:00.0
c# 委托 事件 EventHandler 观察者模式 详解,以及和java的比较


C#和java比较: java中使用的是接口。

C#使用委托机制,可以用时 + 运算符进行注册,直接多播。 而java中是一般是使用一个集合来保存观察者。


发布者(Publisher)= 被观察者 (Observable) = 事件源(java中的EventObject,C#中的sender)

订阅者(Subscriber)=观察者(Observer)     = 接收者(java中继承EventLister,接口, 或Observer接口, C#由于委托机制,不需要继承接口,直接按EventHandler实现回调方法


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

在典型的 C# Windows 窗体或 Web 应用程序中,可订阅由控件(如按钮和列表框)引发的事件。可使用 Visual C# 集成开发环境 (IDE) 来浏览控件发布的事件,选择要处理的事件。IDE 会自动添加空事件处理程序方法和订阅事件的代码。


EventHandler为C#中的预定义委托,专用于表示不生成数据的事件的事件的处理程序方法。

public delegate void EventHandler(	Object sender,	EventArgs e)

事件概述

事件具有以下特点:

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

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

  • 没有订户的事件永远不会被调用。

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

  • 如果一个事件有多个订户,当引发该事件时,会同步调用多个事件处理程序。要异步调用事件,请参见使用异步方式调用同步方法。

  • 可以利用事件同步线程。

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

看下面的代码,比较详细了!

下面的示例演示了上述步骤,它将自定义 EventArgs 类和 EventHandler<T> 用作事件类型。

MSDN的实例还不错,直接拿来用了。给翻译了一下,重点部分已注释!

namespace ConsoleApplication2{    using System;    using System.Collections.Generic;    // 自定义一个事件类来保存事件信息    public class CustomEventArgs : EventArgs    {        public CustomEventArgs(string s)        {            message = s;        }        private string message;        public string Message        {            get { return message; }            set { message = value; }        }    }    // 广播事件的类    class Publisher    {        // 使用 EventHandler<T> 声明一个事件        public event EventHandler<CustomEventArgs> RaiseCustomEvent;        //这个方法是做了一些事情。 然后触发一个事件。        public void DoSomething()        {            //DoSomething…………            // 你也可以再触发事件前,执行一些其他的代码            OnRaiseCustomEvent(new CustomEventArgs("Did something,hi 这是事件消息"));        }                //使用虚方法,让子类可以重写。 to allow derived classes to override the event invocation behavior        protected virtual void OnRaiseCustomEvent(CustomEventArgs e)        {            // 定义一个局部变量,已防止最后一个订阅者刚好在检查null后取消订阅            EventHandler<CustomEventArgs> handler = RaiseCustomEvent;            // 如果没有 订阅者(观察者), 委托对象将为null            if (handler != null)            {                // 格式化事件消息中 的字符串                e.Message += String.Format(" at {0}", DateTime.Now.ToString());                // 这是最重要的一句。                // 此时执行的  handler已经是一个多播委托(如果有多个订阅者或观察者注册)。                // 既然是多播委托,就可以依次调用各个 回调函数 (既然是回调函数,实际的执行就由订阅者类决定)。                //这里面传入一个this, 就代表 事件源(或发布者 或 被观察者 都一个意思)                handler(this, e);            }        }    }    //用来注册事件的类    class Subscriber    {        private string id;        public Subscriber(string ID, Publisher pub)        {            id = ID;            // 注册事件,使用C#2.0语法            //注册这个动作,应该有订阅者主动进行,并且可以再后期取消注册            pub.RaiseCustomEvent += HandleCustomEvent;        }        // 实现回调函数。 在事件发生后,执行什么样的操作。这里只是简单的打印信息。        void HandleCustomEvent(object sender, CustomEventArgs e)        {            //这就是实际的操作。            Console.WriteLine(id + " received this message: {0}", e.Message);        }    }    class Class1    {        static void Main(string[] args)        {            Publisher pub = new Publisher();            Subscriber sub1 = new Subscriber("sub1", pub);            Subscriber sub2 = new Subscriber("sub2", pub);            // 调用这个方法来产生事件            pub.DoSomething();            // Keep the console window open            Console.WriteLine("Press Enter to close this window.");            Console.ReadLine();        }    }    }




1楼gaotong2055昨天 20:32
http://msdn.microsoft.com/zh-cn/library/ms173172(v=vs.80).aspxn官方的文档
  相关解决方案