C#事件的发送方和接收方(订阅方)

基于Windows的应用程序也是基于消息的,Windows使用预定义消息与应用程序通讯。.NET Framework将Windows消息封装在事件中,可以把事件作为对象之间的通讯介质。

事件发送方:发送事件的对象事件接收方:捕获事件并对其作出响应的对象(处理事件)在事件通讯机制中,事件发送方不知道哪个对象将接收到它引发的事件以及进行什么样的处理,事件发送方不知道谁将是事件接收方,它只是将"事件发生了"这个消息广播出去。

在C#中,事件机制是借助委托来实现的。一个事件就相当于一个委托实例。

----------------------------------------------------------------------

使用事件:使用事件分为4步,与使用委托有一点小区别。1.定义一个委托类型。  这一步与使用委托没有什么不同,一般都使用 .Net预定义的委托。

2.定义一个事件名(在事件发送方中)。  访问控制符 event 委托类型名 事件名;

3.封装事件,即将事件处理方法注册到事件中(事件处理方法定义在事件接收方中)。  事件发送方.事件名 += new 委托类型名(事件处理方法);

事件名即相当于委托实例名,事件处理方法即相当于委托实例的关联方法。只不过,在事件机制中,将定义委托实例(使用委托的第二步)分为两个步骤,分别由事件发送方和接收方来进行: 定义一个事件名 - 得到一个委托实例名 (事件发送方) ;封装该事件 - 得到一个关联方法(将一个事件处理方法与一个事件关联) (事件接收方)。注:在事件发送方定义事件名时,可以将事件名声明为static的,以便事件接收方封装事件

4.事件发送方引发事件,事件接收方的事件处理方法捕获并处理事件。引发事件(相当于调用委托实例)即会导致事件处理方法的执行(相当于委托实例的关联方法的执行)事件可能由用户的操作(比如单击鼠标)引发,也可能由某些其他的程序逻辑触发;

--------------------------------------------------------------------?using System;

namespace EventExample{class ClassReceive   //事件接收方    {        [STAThread]static void Main(string[] args)        {            ClassSend Send = new ClassSend();

//3.封装事件            Send.CalculateFinished += new MyDelegate(Send_CalculateFinished);

//执行下面三行,将导致三次引发MyClass的CalaculatedFinished事件            Send.Square(2); //调用事件发送方的代码,导致事件被引发            Send.Cube(2); //调用事件发送方的代码,导致事件被引发            Send.Double(2); //调用事件发送方的代码,导致事件被引发            Console.ReadLine();        }//定义事件处理方法,在事件被引发后执行        private static void Send_CalculateFinished(string msg)        {            Console.WriteLine(msg + "计算完成");        }    }

//1.定义委托,指定返回类型和形参列表。与类定义一样,同在命名空间下    delegate void MyDelegate(string msg);

class ClassSend    //事件发送方    {//2.定义事件CalculateFinished,该事件属于MyClass类        public event MyDelegate CalculateFinished;

//4.执行该方法事件将被引发,一般由事件接受方调用该方法来触发事件        public void OnCalculateFinished(string msg)        {//判断事件是否为空,事件接受方如果定义了事件的处理方法,则不为null            if (CalculateFinished != null)            {//如果事件为空就触发事件,将导致一个空引用异常                CalculateFinished(msg);//就是这一句引发事件,即: 事件名(形参列表);//此方法的形参列表已经由与事件相关的委托指定了            }        }

public void Square(float x)        {float result = x * x;            Console.WriteLine("{0}的平方等于:{1}", x, result);//执行事件引发方法,将导致事件被引发            OnCalculateFinished("平方");        }public void Cube(float x)        {float result = x * x * x;            Console.WriteLine("{0}的立方等于:{1}", x, result);//执行事件引发方法,将导致事件被引发            OnCalculateFinished("立方");        }public void Double(float x)        {float result = 2 * x;            Console.WriteLine("{0}的倍数等于:{1}", x, result);//执行事件引发方法,将导致事件被引发            OnCalculateFinished("倍数");        }    }}

--------------------------------------------------------------------

事件是多点委托,对事件只能使用 += 和 -= 运算,= 运算对于事件是无效的。

.NET 提供了一个预定义的用于事件的委托类型 - EventHandlerpublic delegate void EventHandler(Object sender,EventArgs e);  参数sender是引发事件的事件发送方对象,e是事件的有关数据  在定义事件时,可以不必自定义委托类型,直接使用这个预定义的事件委托类型就可以了。

自定义事件时,应该遵守一些命名规范:  使用动词命名事件,最好带上现在、进行或完成时态来描述事件的触发时效;  事件的委托类型的命名一般以"EventHandler"为后缀,事件参数类名称以"EventArgs"为后缀;  总是使用 sender 和 e 来命名事件中的两个参数;  事件发送方中,引发事件的方法的命名一般用 On + 事件名 eg:OnCalaculateFinished(string msg);

在事件发送方类中,定义引发事件的方法(其中包含调用事件的语句)时,必须先判断事件是否为空,因为事件是在接收方中封装的(定义事件处理方法),事件发送方无法知晓是否存在有事件处理方法(发送方不知道接收方的存在),所以在事件发送方中引发事件的代码处,必须先判断事件是否为空。另外,往往是在事件接收方中,调用了事件发送方的代码,然后导致事件被引发,因而,在事件接收方中,封装事件的代码应该先于调用事件发送方的代码执行。

转载于:https://www.cnblogs.com/Holmes-Jin/archive/2012/03/16/2399721.html

C#事件的发送方和接收方(订阅方)相关推荐

  1. 事件传递 java_将事件传递/发送到父组件?

    在Angular中,我可以创建一个发出动作的子组件: @Component({ ... template: ` Click Me ` }) export class ChildComponent { ...

  2. 80×60长40米的地笼_石家庄Q345矩形方管 220*80*8方管 华东地区

    摘要: 石家庄Q345矩形方管 220*80*8方管 华东地区 无锡征图钢业有限公司是一家以生产矩形钢管为主的方管厂作为专业矩管生产,无缝方管生产企业,矩形钢管生产工艺采用先进的热轧钢管生产线生产,产 ...

  3. html5怎么引入苹方简,css 引入苹方字体

    苹方提供了六个字重,font-family 定义如下: 苹方-简 常规体 font-family: PingFangSC-Regular, sans-serif; 苹方-简 极细体 font-fami ...

  4. 二次拟合r方_回归分析中R方和调整R方的区别

    作者|ANIRUDDHA BHANDARI 编译|VK 来源|Analytics Vidhya 概述 理解R方和调整R方的概念 了解R方和调整R方之间的关键区别 介绍 当我开始我的数据科学之旅时,我探 ...

  5. chan队列之发送方等待接收方处理结果

    从一个nil通道中接收元素,当前goroutine会阻塞 向一个nil通道中发送元素,当前gotoutine也会阻塞 向一个已关闭的通道中发送元素,会引发一个运行时panic,即使发送操作因通道已满而 ...

  6. 【EventBus】EventBus 源码解析 ( 事件发送 | 线程池中执行订阅方法 )

    文章目录 一.EventBus 中主线程支持类 二.EventBus 中 AsyncPoster 分析 三.AsyncPoster 线程池 Runnable 任务类 一.EventBus 中主线程支持 ...

  7. 基础篇:事件的发送和处理

    在ActionScript3.0中,Event类属性有:type.cancelable.target.currentTarget.eventphase.bubles Event方法有:clone(). ...

  8. 2008系统服务器日志在哪里,windows-server-2008 – 如何将Windows Server 2008事件日志发送到syslog服务器?...

    Snare for Windows Vista is a Windows 2008 and Windows Vista compatible service that interacts with t ...

  9. 元素方尖服务器维护,元素方尖公测版

    元素方尖公测版是一款相当惊险刺激的动作冒险类手游,玩家在游戏中可以选择自己喜欢的职业进行战斗冒险,诸多的副本挑战以及趣味玩法等你来尝试,收集一身极品装备让自己成为异世界大陆的最强者.你将扮演一名家园毁 ...

最新文章

  1. pmp知识点详解-项目大牛整理_PMP核心知识点—第五章:项目范围管理(1)
  2. Java动态生成类以及动态添加属性 本篇文章来源于 Linux公社网站(www.linuxidc.c
  3. win8iis和php,Win8下IIS装PHP扩展
  4. CMSampleBufferRef 转换为UIImage
  5. Linux测试端口的连通性的四种方法
  6. Windows和Linux双启动,并用在Windows下配置CoLinux启动
  7. 使用二进制的方式安装mysql实践纪要
  8. http服务器异步响应,python – 具有异步响应的Twisted http服务器,其中请求必须等待数据变为可用或超时...
  9. c++ eos智能合约开发_[EOS智能合约]第二节:用EOS开发一个To-do List小应用
  10. 链表(Linked List)之双向链表
  11. LeetCode 374. 猜数字大小(二分查找)
  12. 敏捷无敌之重任在肩(7)
  13. 金额与数字转化常用实用几个JS方法
  14. 关于OATUH中的AUTHRAZITON CODE和TOKEN的关系,实际上就是这么回事
  15. nginx源码分析——filter模块
  16. 逆向分析商业软件 010 Editor 及注册机编写
  17. Ubuntu 16.04 快捷键截图
  18. Tableau实战 网站客户细分仪表盘
  19. 文字图片白底黑字_白底黑字简短文字图片 白底黑字纯简短文字
  20. 一个IP账号,为啥通过路由器就可供多人同时使用?

热门文章

  1. python将变量a全部变成大写字母_每天一个Python知识点:只用一招就将所有的英文单词首字母变成大写...
  2. 税友报税软件让修改服务器地址,税友报税软件让修改服务器地址
  3. c语言以空格分割字符串_C语言: 利用sscanf() 函数分割字符串
  4. linux子系统使用rstudio,linux 下安装Rstudio
  5. 量子计算机与人脑接口,量子信息科学:量子计算机、隐形传物与人脑量子运算...
  6. LabVIEW实现PCB电路板元器件匹配定位(实战篇—7)
  7. 【camera】2.相机成像原理和数学模型
  8. 一次失败的Pytorch模型量化尝试
  9. docker安装redis提示没有日记写入权限_对 Redis 在 Windows 下的利用方式思考
  10. cstring 比较_不同商用齿轮齿接触分析软件的比较(三)