zoukankan      html  css  js  c++  java
  • C# EventHandler观察者模式

    C# EventHandler观察者模式
    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
    )
    事件具有以下特点:
    1.发行者确定何时引发事件,订户确定执行何种操作来响应该事件。
    2.一个事件可以有多个订户。一个订户可处理来自多个发行者的多个事件。
    3.没有订户的事件永远不会被调用。
    4.事件通常用于通知用户操作(如:图形用户界面中的按钮单击或菜单选择操作)。
    5.如果一个事件有多个订户,当引发该事件时,会同步调用多个事件处理程序。要异步调用事件,请参见使用异步方式调用同步方法。
    6.可以利用事件同步线程。
    7.在 .NET Framework 类库中,事件是基于 EventHandler 委托和 EventArgs 基类的。

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

    复制代码
    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();
        }
    }
    

    }
    复制代码

  • 相关阅读:
    PAT A1094 The Largest Generation (25 分)——树的bfs遍历
    PAT A1055 The World's Richest (25 分)——排序
    PAT A1052 Linked List Sorting (25 分)——链表,排序
    PAT A1076 Forwards on Weibo (30 分)——图的bfs
    辅导员
    辅导员面试
    C程序设计
    Excel VBA 基本概念
    Excel函数
    导入excel表的数据到数据库ssh
  • 原文地址:https://www.cnblogs.com/grj001/p/12224365.html
Copyright © 2011-2022 走看看