铁血规则:事件预订与取消预订

  在编码的时候,我们经常预订某个事件来处理它,但很少取消事件的预订,这种做法可能导致程序在运行时出现一些异常。

      如果你的某个用于处理事件的对象不是在运行期内永久存在的(比如,不是Singleton对象),那么请记住一条规则:在该对象(事件预订者)的生命周期中只要预订了其他对象(事件发布者)的事件,那么在该对象释放时,一定要取消这些事件的预订。否则,在预订者被释放后,发布者仍然保持着预订者的引用,在对应的事件被触发时,发布者仍然会持有预订者的引用(导致内存泄露),并且调用预订者的处理函数,而由于预订者已经被释放,所以可能引发莫名其妙的问题。(这条规则很早就总结出来了,最近却忘记了,以至于浪费了半天的时间来跟踪一个奇怪的现象。以此记录作为前车之鉴,呵呵)

      实践这条规则很简单,一般这样做就可以了:

(1)在预订者的构造函数或初始化函数中预订事件。

(2)在预订者的析构函数或Dispose方法中取消事件预订。

      比如:

    public class Publisher
    {
        
public event CbGeneric SomeEvent;
    }

    
public class Subscriber :IDisposable
    {
        
private Publisher publisher;

        
public Subscriber(Publisher _publisher)
        {
            
this.publisher = _publisher ;
            
//预订事件
            this.publisher.SomeEvent += new CbGeneric(publisher_SomeEvent);
        }

        
void publisher_SomeEvent()
        {
            
//处理事件
        }

        
public void Dispose()
        {
            
//取消预订
            this.publisher.SomeEvent -= new CbGeneric(publisher_SomeEvent);
        }
    }

      特别是当预订者是自定义的windows控件时(从Control类继承),我们可以在其自身的Disposed事件中,来取消对发布者的事件预订。当包含该控件对象的宿主Form被关闭时,控件对象也会被释放,这可能是一个很隐蔽的问题,以至于我们忘了在控件被释放时取消必须的事件预订。

      我们也许想到,如果发布者与预订者的生命周期是完全相同的,是不是就不需要取消预订了?大多数情况下是可以的,但是你要保证你的发布者对象在被释放后,是否还被其他的对象持有引用,这样也可能会导致内存泄露以及其他问题。所以,我们建议,既然预订了事件,就请在预订者被释放时,取消这些预订。

 

 

 

 

转载于:https://www.cnblogs.com/zhuweisky/archive/2011/04/07/2008145.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/462698.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL中的insert ignore into讲解

最近工作中,使用到了insert ignore into语法,感觉这个语法还是挺有用的,就记录下来做个总结。 insert ignore into : 忽略重复的记录,直接插入数据。 包括两种场景: 1、插入的数据是主键冲突时 insert ignore into…

[置顶] 我的iOS作品

我的iOS作品 罗朝辉 ( http://blog.csdn.net/kesalin)CC 许可,转载请注明出处前言 做了好几年的 iOS 开发了,业余也零零散散地写了不少代码和博文教程。可惜一直都没有整理下,上次过年回家在张江广兰路把笔记本给丢了,损失惨重&am…

SSM框架搭建

SSM(SpringSpringMvcMybatis)项目环境搭建: 1、项目环境: jdk-1.8 tomcat-9.0 mysql-5.1.44 spring 5.1.6 mybatis 3.5.1 maven 3.5.42、项目目录结构: 3、pom.xml中引入的依赖&#xf…

MySQL字段值大小写敏感的解决方案

最近在用开源的MySQL 8.0开发本公司的产品,在客户现场建表时默认使用的是CHARSETutf8mb4 COLLATEutf8mb4_0900_ai_ci 字符集导致与oracle的结果不一致,最后将建表时的字符集改为utf8mb3就可以了。 正常建表如下,默认使用的是CHARSETutf8mb4 …

制作Slider组件

利用as3,我们可以尝试制作一些有趣的组件,虽然现在已经有很多实用的组件,但是自己尝试写一下也是不错的。利用as3语法,借用了绘图Api我们尝试制作一下这个组件。因为我们不需要很强大的功能,对此我们只是需要选取其一部…

Android 编程下的四大组件之服务(Service)

服务(Service) 是一种在后台运行,没有界面的组件,由其他组件调用开始。Android 中的服务和 Windows 中的服务是类似的东西,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序。 服务&#xf…

mysql ld preload过程

纯手工打造每一篇开源资讯与技术干货,数十万程序员和Linuxer已经关注。 导读 本文将叙述通过二进制源码方式安装Percona-5.7.15,并进行快速启动。这边如何使用二进制版本安装Percona-5.7.15就不说了,和之前一模一样。 不做多余的事 1、解…

第六章实验报告(函数和宏定义实验)

C程序设计实验报告 一、实验项目: 1、编写由三角形三边求面积的函数 2、编写求N阶乘的函数 3、求两个整数的最大公约数 4、打印输出三角形 5、求500以内的所有亲密数对 姓名:廖云福 实验地点:教学楼514教室  实验时间:2019.4.30 一、实验目…

HttpRequest 与HttpWebRequest 有什么区别

System.Web.HttpRequest是封装浏览器对服务器的请求的,主要用在ASP.NET中,其中包括浏览器请求的网址,查询字符串数据或表单数据等等 而System.Net.HttpWebRequest则是用来简化网络请求的过程,从服务器上获取文件/结果的&#xff0…

mysqld_safe启动脚本源码阅读与分析

原文链接:https://blog.csdn.net/weixin_39844426/article/details/113422137 前几天读了下mysqld_safe脚本,个人感觉还是收获蛮大的,其中细致的交代了MySQL数据库的启动流程,包括查找MySQL相关目录,解析配置文件以及…

统计文章中字母出现频率

代码位置:https://github.com/Evilleon/article-vocabulary/letter转载于:https://www.cnblogs.com/YXSZ/p/10809930.html

mapreduce shuffle过程问答

通过hadoop权威指南学习hadoop,对shuffle过程一直很疑惑,经过查看网上多个帖子,最终 完成此篇问答总结。 1.什么叫shuffle 从map任务输出到reducer任务输入之间的过程就叫做shuffle 2.每个map任务都有对应的缓存吗?默认是多少&…

Oracle为JDK 8寻求社区参与

据InfoQ报道,随着Java 7功能的日益完备,Oracle正在将注意力转向JDK 8,Java平台组的首席架构师Mark Reinhold正在寻求Java社区的参与: 我们已经知道JDK 8中会有一些大家伙,同时也会为其他大大小小的特性留下空间。因此需…

ubuntu下安装pt-query-digest

最近在改造开发MySQL时要使用pt-query-digest工具分析性能问题,一路遇到了一些问题,记录下来便于日后翻看。 系统: #45~20.04.1-Ubuntu SMP Mon Apr 4 09:38:31 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux 在安装过程中遇到了很多的问题&#…

S2-016、S2-017

前言 由于S2-016、S2-017出现的原因时相同的,只是由于poc不一样,造成了不同的攻击。S2-016是RCE,S2-017是开发型重定向漏洞。这里将两个漏洞放一起分析。另外“Struts2系列起始篇”是我整各系列的核心,希望大家能花些时间先看看。…

struts 2 配置通配符

2019独角兽企业重金招聘Python工程师标准>>> 随着Web应用程序的增加,所需的Action也会更多,从而导致大量的action映射,使用通配符可以减少action配置的数量,使一些具有类似行为的Action或者Action方法可以使用通用的样…

image to pdf

public void ExportDataIntoPDF(string pathName, String path){//导出至PDFiTextSharp.text.Document document new iTextSharp.text.Document(); try{iTextSharp .text .pdf .PdfWriter .GetInstance (document, new FileStream(pathName, FileMode.CreateNew ));document.O…

Mysql索引类型分析

一、简介MySQL目前主要有以下几种索引类型:1.普通索引2.唯一索引3.主键索引4.组合索引5.全文索引二、语句CREATE TABLE table_name[col_name data type][unique|fulltext][index|key][index_name](col_name[length])[asc|desc] 1.unique|fulltext为可选参数&#xf…

记一次使用pt-query-digest工具分析MySQL慢查询日志

最近遇到了MySQL性能问题,使用percona 的 pt-query-digest工具分析性能的瓶颈点。并且pt-query-digest工具要优于MySQL本身自带的mysqldumpslow工具。 查看pt-query-digest工具在ubuntu下的安装流程请看:ubuntu下安装pt-query-digest_一缕阳光a的博客-CS…

App 运营的指标具体都有哪些?(四)

因产品而异,要看产品类型的工具类,启动次数很重要;社区类,活跃用户和UGC很重要;游戏,在线人数和arpu值是关键。。。转载于:https://blog.51cto.com/yerik/1166365