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

如果你的某个用于处理事件的对象不是在运行期内永久存在的(比如,不是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

铁血规则:事件预订与取消预订相关推荐

  1. 铁血规则:事件预订与取消预订[转]

    铁血规则:事件预订与取消预订 在编码的时候,我们经常预订某个事件来处理它,但很少取消事件的预订,这种做法可能导致程序在运行时出现一些异常. 如果你的某个用于处理事件的对象不是在运行期内永久存在的(比如 ...

  2. 酒店取消预订预测分析报告

    分析背景及目的 本次分析的数据源来自:hotel_bookings-数据集-kaggle官网,是一份酒店预订的信息数据,共119391行,数据集各个待分析字段的含义如下: 数据类型 字段名 字段含义 ...

  3. 一个取消事件的简单js例子(事件冒泡与取消默认行为)

    先上代码: <div id='outer' onclick='alert("我是outer")'><div id="middle" oncli ...

  4. 实例:用C#.NET手把手教你做微信公众号开发(13)--事件消息处理之取消关注

    一.取消关注事件 用户在取消关注公众号时,微信会把这个事件推送到开发者填写的URL,方便开发者做帐号的解绑等处理. <xml><ToUserName><![CDATA[t ...

  5. 【EventBus】事件通信框架 ( 取消注册 | 获取事件参数类型 | 根据事件类型获取订阅者 | 移除相关订阅者 )

    文章目录 一.取消注册订阅者 二.完整代码示例 一.取消注册订阅者 取消注册操作 : 从 Map<Object, List<Class<?>>> typesBySu ...

  6. 事件 绑定,取消冒泡,拖拽 ,点击,事件委托习题

    事件知识的,冒泡,绑定,委托 <script type="text/javascript">//事件绑定 取消 var div=document.getElements ...

  7. jQuery事件2——off取消事件绑定

    作用:取消事件的绑定,传参如下例 先对div绑定两个点击事件,两个鼠标移出事件,效果如下 代码 <!DOCTYPE html> <html lang="en"&g ...

  8. vue中el-radio-group点击事件,双击取消

    vue中el-radio-group点击事件 普通用法 需要实现双击取消 普通用法 需要注意,如果@change事件除了当前选中的单选按钮的label值,还需要带上另外的参数,则需要用event来代替 ...

  9. sharepoint 2010 会议室预订系统-资源预订系统

    由于现在有很多企业或者公司,其办公楼层会议室比较多,预订情况不能及时得知,为了能进一步规范和管理这些会议室资源,更好的提高办公会议室的资源使用率,提高组织者安排会议的效率,需要有一套比较成熟的会议室预 ...

最新文章

  1. hadoop hdfs总结 NameNode部分 1
  2. Qt for QNX
  3. 工具-eclipse-hibernate关于快速生成*.hbm.xml文件,与bean文件的操作,不使用hibernate tool解决办法之一,主要为了快速开发,写的小工具
  4. 使用git remote提交代码
  5. azkaban 与 java任务_azkaban任务报错java.lang.RuntimeException: The root scratch dir: /tmp/hive...
  6. document.body.scrollTop用法
  7. php列表调多图,列表中调用多图显示的文章
  8. cmake release和debug代码运行效果不一样_这35个小细节,让你的Java 代码运行效率翻倍!...
  9. 为AI芯片铺路?原三星半导体周军加盟Rokid
  10. UVa1587 - Box
  11. 【编译原理】自上而下语法分析(C/C++源码+实验报告)
  12. windows 系统快捷键小技巧
  13. 制作软件工程师风格的qq头像
  14. JQuery中美元符号$
  15. 微信语音识别开放平台
  16. office2010专业版
  17. Angular实现微博发布功能
  18. 松弛法求解给定边界条件的泊松方程
  19. leetcode 179 最大数
  20. 龙芯3A5000参数 龙芯3A5000怎么样

热门文章

  1. php字符串变量,PHP 字符串变量
  2. Linux学习:第四章-vi编辑器
  3. 项目积压需求项目计划_需求变更频繁,项目经理如何做好需求管理?
  4. leetcode71. 简化路径 Unix 风格
  5. redis——客户端
  6. 橙白oj18训练作业1-题解、代码
  7. UNIX(进程间通信):04---孤儿进程
  8. C++11学习 新特性之 “=default” 、“=delete”
  9. codeforces 96A-C语言解题报告
  10. 最长重复子串和最长不重复子串求解