在WPF中应用弱事件模式
http://www.cnblogs.com/rickiedu/archive/2007/03/15/676021.html
在wpf中应用弱事件模式
对于已经在CSDN 上混了N个裤衩的你来说,以上情景绝非痴人说梦,恰恰相反,这些简直就是理所当然的。说句实在话,偶也一直认为生活就是那么简单美好,直到昨天偶在摆弄WPF的时候居然碰到了一个费解的问题,还是代码来说话吧。
XAML:













CS:


































运行,任意点击按钮A,B,C,D ,弹出来的对话框忠实地报告了你所点击的按钮。按一下按钮“干掉打小报告的”,再挑个按钮点点看。怪事出现了,怎么还有人再打小报告啊???Debug进去,_spy的确给置空了,但是button_Click仍会执行,分明_spy没有被销毁嘛,难道GC跟_spy有一腿?算了,还是别胡思乱想了,老老实实地拜访Gooooooooogle吧。真是不查不知道,一查吓一跳。先译一段MSDN里面的话吧:
侦听事件可能会导致内存泄露。侦听事件的典型做法是把处理方法附加到事件源上,具体写法因编程语言而异。举例而言,在C#中的写法是:source.SomeEvent += new SomeEventHandler(MyEventHandler) 。这种方法产生一个从事件源到侦听者的强引用。一般来说,除非显示去除侦听关系,侦听事件使得侦听者的生命期受到事件源生命期的制约。而在现实情况中,你可能并不想让侦听者的生命期依赖于事件源,而是希望用一些其他的因素(比如它是否属于当前的视觉树)来控制。当事件源的生命期超过侦听者的时候,常规的事件模式就会导致内存泄露:侦听者的存活超过了想要的时间。
乖乖,一直习以为常的写法居然有这么严重的隐患,难道是偶得人品太好所以才一直没有出大问题?喝口水,继续看MSDN:
一般而言,负责开发控件的程序员。。。。。。
怪不得偶一直没有出大问题,原来起作用的不是偶的人品,而是因为偶没有写过几个自定义控件:)
MSDN写的一如既往地晦涩拗口,翻来覆去看了几个来回才懂了个大概,下面来理理思路:
假设有一个类DemoClass公开了DemoEvent事件,ListenerClass的实例listener希望侦听了前者的实例demo的DemoEvent事件。如果是通过 += 的方式来侦听,那么在demo被销毁之前,listener无法被销毁。拿前面的代码来举例吧,_spy侦听了button的Click事件,虽然在_btnKillSpy_Click里面貌似干掉了_spy,但是你点击按钮A,B,C,D,仍然会有人打小报告。到底为啥呢?因为在.net对委托和事件的实现中,当listener侦听了demo的某个事件时,就隐式创建了一个对listener的强引用,任凭你怎么折腾GC,实际的listener对象在demo销毁之前是不会被销毁回收的。至于什么是强引用,偶就这里就不解释了,不明白的看这里。可想而知,当listener侦听了多个其他对象的事件时,情况就变得更加糟糕。网上有关于如何在.net 2.0中解决该问题的blog,也有人说实际上该问题究其本质还是程序员的写法有问题,对clr的理解不够…… 偶才疏学浅,就不参与争论了,这里单单说说在.net 3.0中如何解决这个问题。
可以看到,问题的症结其实就在于那个隐式创建的对侦听者的强引用,很容易想到的一个解决方法就是化强为弱,因为弱引用不会阻止GC的回收行为。WPF中就是以这个思想为指导引入了一个所谓的弱事件模式。具体而言,WPF提供了一个接口和一个类来实现该模式,分别为 IWeakEventListener和WeakEventManager。
IWeakEventListener接口定义了希望以弱事件模式侦听事件的类的公约,而WeakEventManager为封装弱事件管理逻辑提供了基类。对于上文中的例子而言,要应用弱事件模式,则SPY类应实现IWeakEventListener,另外为按钮的Click事件添加一个继承于WeakEventManager的管理类。
IWeakEventListener接口仅包含一个方法:
bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs e);
侦听者在该方法中依据传入的managerType来识别事件的类型,并分发给相应的处理方法。
WeakEventManager包含的东西相对较多一些,这里就不一一赘述,大家看代码里面的注释吧。
CS:











































































在WPF中应用弱事件模式的更多相关文章
- WPF程序中的弱事件模式
在C#中,得益于强大的GC机制,使得我们开发程序变得非常简单,很多时候我们只需要管使用,而并不需要关心什么时候释放资源.但是,GC有的时并不是按照我们所期望的方式工作. 例如,我想实现一个在窗口的标题 ...
- 【转载】详细解读C#中的 .NET 弱事件模式
你可能知道,事件处理是内存泄漏的一个常见来源,它由不再使用的对象存留产生,你也许认为它们应该已经被回收了,但不是,并有充分的理由. 在这个短文中(期望如此),我会在 .Net 框架的上下文事件处理中展 ...
- C#中的 .NET 弱事件模式
引言 你可能知道,事件处理是内存泄漏的一个常见来源,它由不再使用的对象存留产生,你也许认为它们应该已经被回收了,但不是,并有充分的理由. 在这个短文中(期望如此),我会在 .Net 框架的上下文事件处 ...
- 整理:WPF中应用附加事件制作可以绑定命令的其他事件
原文:整理:WPF中应用附加事件制作可以绑定命令的其他事件 目的:应用附加事件的方式定义可以绑定的事件,如MouseLeftButton.MouseDouble等等 一.定义属于Control的附加事 ...
- WPF中的路由事件(转)
出处:https://www.cnblogs.com/JerryWang1991/archive/2013/03/29/2981103.html 最近因为工作需要学习WPF方面的知识,因为以前只关注的 ...
- WPF中的Command事件绑定
在项目中使用Command绑定能够使我们的代码更加的符合MVVM模式.不了解的同学可能不清楚,只有继承自ButtonBase类的元素才可以直接绑定Command(Button.CheckBox.Rad ...
- WPF中自定义路由事件
public class MyButtonSimple: Button { // Create a custom routed event by first registering a RoutedE ...
- WPF 中的 路由事件
public class ReportTimeEventArgs:RoutedEventArgs { public ReportTimeEventArgs(RoutedEvent routedEven ...
- WPF 弱事件
因为在接触WPF的过程中追查INotifyPropertyChanged的通知原理的时候,发现了 PropertyChangedEventManager这个类,它是继承与WeakEventManage ...
随机推荐
- python2.7入门---字符串
这次咱们就来看一下python的字符串类型.首先我们要知道,字符串是 Python 中最常用的数据类型.我们可以使用引号('或")来创建字符串.创建字符串很简单,只要为变量分配一个值 ...
- mysql字符串拼接,存储过程
添加字段: alter table `user_movement_log`Add column GatewayId int not null default 0 AFTER `Regionid` (在 ...
- stm8编程tips(stvd)
编译完成时显示程序占用的flash和ram大小 将附件压缩包中的mapinfo.exe解压到stvd的安装路径\stvd中 在工程上点右键选settings 右侧的选项卡选择Linker,将categ ...
- 【java并发编程】十三章:显式锁:LOCK
java5以后,新增了显式锁,用于当内置锁不能满足需求后可选择的一种高级方案. lock接口的特点 与内置锁一样,他能提供互斥性,内存可见性,可重入等特征,与内置锁不同的是,Lock提供了一种无条件, ...
- Python Flask之旅
<Pyhton Flask之旅> 以前学flask时做的总结,搬运到这里,markdown格式写的有点乱,凑合看吧. 参考博客 http://blog.csdn.net/nunchakus ...
- 阿里云SLB上http强制跳转到https问题处理
背景: 最近一客户有一个需求,需要将外网所有http访问请求强制跳转到https,公网出口使用阿里云SLB,证书放在SLB上,SLB后端实例为ECS(webserver)web服务使用nginx, 网 ...
- 在阿里云上遇见更好的Oracle(三)
鬼扯完“去IOE”,继续回来说说这个系列文章的主角Oracle. 在DB-Engine的数据库排行榜中,Oracle已经占据了多年的第一(最新排名可以点击“阅读原文”).当然因为互联网行业的兴起,My ...
- POJ 2161 Chandelier(动态规划)
Description Lamps-O-Matic company assembles very large chandeliers. A chandelier consists of multipl ...
- HDU B-Ignatius and the Princess IV
http://acm.hdu.edu.cn/showproblem.php?pid=1029 Problem Description "OK, you are not too bad, em ...
- PAT 1045 快速排序
https://pintia.cn/problem-sets/994805260223102976/problems/994805278589960192 著名的快速排序算法里有一个经典的划分过程:我 ...