传统事件publisher和listener是直接相连的,这样会对垃圾回收带来一些问题,例如listener已经不引用任何对象但它仍然被publisher引用

垃圾回收器就不能回收listener所占用的内存以及publisher仍然引用该listener向其触发事件。

而弱事件就解决了这个问题

WeakEventManager是publisher和listener之间的桥梁,从而取代两者之间的直接连接

一、定义WeakEventManager类

public class WeakCarInfoEventManager : WeakEventManager
    {
        public static void AddListener(object source,IWeakEventListener listener)
        {
            CurrentManager.ProtectedAddListener(source, listener);
        }
        public static void RemoveListener(object source,IWeakEventListener listener)
        {
            CurrentManager.ProtectedRemoveListener(source, listener);
        }
        public static WeakCarInfoEventManager CurrentManager
        {
            get
            {
                var manager = GetCurrentManager(typeof(WeakCarInfoEventManager))
                    as WeakCarInfoEventManager;
                if(manager == null)
                {
                    manager = new WeakCarInfoEventManager();
                    SetCurrentManager(typeof(WeakCarInfoEventManager), manager);
                }
                return manager;
            }
        }
        protected override void StartListening(object source)
        {
            (source as CarDealer).NewCarInfo += CarDealer_NewCarInfo;
        }
        void CarDealer_NewCarInfo(object sender,CarInfoEventArgs e)
        {
            DeliverEvent(sender, e);
        }
        protected override void StopListening(object source)
        {
            (source as CarDealer).NewCarInfo -= CarDealer_NewCarInfo;
        }
    }

二、定义事件监听者(listener)

public class Consumer:IWeakEventListener //主要要继承改接口
    {
        private string name;
        public Consumer(string name)
        {
            this.name = name;
        }
        public void NewCarIsHere(object sender,CarInfoEventArgs e)
        {
            Console.WriteLine("{0}:car {1} is new", name, e.Car);
        }
        bool IWeakEventListener.ReceiveWeakEvent(Type managerType,object sender,EventArgs e)
        {
            NewCarIsHere(sender, e as CarInfoEventArgs);
            return true;
        }
    }

三、事件发布者(publisher)

public class CarInfoEventArgs : EventArgs //自定义事件数据参数
    {
        public CarInfoEventArgs(string car)
        {
            this.Car = car;
        }
        public string Car { get; private set; }
    }
    public class CarDealer
    {
        public event EventHandler<CarInfoEventArgs> NewCarInfo;
        public void NewCar(string car)
        {
            Console.WriteLine("Car dealer, new car {0}", car);
            RaiseNewCarInfo(car);
        }
        protected virtual void RaiseNewCarInfo(string car)
        {
            EventHandler<CarInfoEventArgs> newCarInfo = NewCarInfo;
            if (newCarInfo != null)
            {
                newCarInfo(this, new CarInfoEventArgs(car));
            }
        }
    }

四、在启动函数中通过WeakCarInfoEventManager把publisher和listener联系起来

class Program
    {
        static void Main(string[] args)
        {
            var dealer = new CarDealer();
            var tian = new Consumer("tian");
            WeakCarInfoEventManager.AddListener(dealer, tian);

dealer.NewCar("奔驰");

var tian1 = new Consumer("tian1");
            WeakCarInfoEventManager.AddListener(dealer, tian1);

dealer.NewCar("东风");
            Console.ReadKey();
        }
    }

运行结果如下:

最后.net4.5版本已经将weakeventmanager集成进来这样使用会更加方便

static void Main(string[] args)
        {
            var dealer = new CarDealer();
            var tian = new Consumer("tian");
            //WeakCarInfoEventManager.AddListener(dealer, tian);
            WeakEventManager<CarDealer, CarInfoEventArgs>.AddHandler(dealer, "NewCarInfo", tian.NewCarIsHere);

dealer.NewCar("奔驰");

var tian1 = new Consumer("tian1");
            //WeakCarInfoEventManager.AddListener(dealer, tian1);
            WeakEventManager<CarDealer, CarInfoEventArgs>.AddHandler(dealer, "NewCarInfo", tian1.NewCarIsHere);

dealer.NewCar("东风");
            Console.ReadKey();
        }

与上面的运行结果是一样的

c#弱事件(weak event)的更多相关文章

  1. 【转载】详细解读C#中的 .NET 弱事件模式

    你可能知道,事件处理是内存泄漏的一个常见来源,它由不再使用的对象存留产生,你也许认为它们应该已经被回收了,但不是,并有充分的理由. 在这个短文中(期望如此),我会在 .Net 框架的上下文事件处理中展 ...

  2. WPF: 深入理解 Weak Event 模型

    在之前写的一篇文章(XAML: 自定义控件中事件处理的最佳实践)中,我们曾提到了在 .NET 中如果事件没有反注册,将会引起内存泄露.这主要是因为当事件源会对事件监听者产生一个强引用,导致事件监听者无 ...

  3. C#中的 .NET 弱事件模式

    引言 你可能知道,事件处理是内存泄漏的一个常见来源,它由不再使用的对象存留产生,你也许认为它们应该已经被回收了,但不是,并有充分的理由. 在这个短文中(期望如此),我会在 .Net 框架的上下文事件处 ...

  4. [AaronYang]C#人爱学不学8[事件和.net4.5的弱事件深入浅出]

    没有伟大的愿望,就没有伟大的天才--Aaronyang的博客(www.ayjs.net)-www.8mi.me 1. 事件-我的讲法 老师常告诉我,事件是特殊的委托,为委托提供了一种发布/订阅机制. ...

  5. WPF 弱事件

    因为在接触WPF的过程中追查INotifyPropertyChanged的通知原理的时候,发现了 PropertyChangedEventManager这个类,它是继承与WeakEventManage ...

  6. .net4.5的弱事件

    .net4.5的弱事件 没有伟大的愿望,就没有伟大的天才--Aaronyang的博客(www.ayjs.net)-www.8mi.me 1. 事件-我的讲法 老师常告诉我,事件是特殊的委托,为委托提供 ...

  7. WPF程序中的弱事件模式

    在C#中,得益于强大的GC机制,使得我们开发程序变得非常简单,很多时候我们只需要管使用,而并不需要关心什么时候释放资源.但是,GC有的时并不是按照我们所期望的方式工作. 例如,我想实现一个在窗口的标题 ...

  8. [DOM Event Learning] Section 2 概念梳理 什么是事件 DOM Event

    [DOM Event Learning] Section 2 概念梳理 什么是事件 DOM Event   事件 事件(Event)是用来通知代码,一些有趣的事情发生了. 每一个Event都会被一个E ...

  9. 事件(event),正则

    1.事件(event):事件是可以被 JavaScript 侦测到的行为.网页中的每个元素都可以产生某些可以触发 JavaScript 函数的事件.2.事件源: 触发事件的元素 事件: 被 JavaS ...

随机推荐

  1. [原]iOS Makefile Template

    export DEVELOPER_DIR := $(shell xcode-select --print-path) PLATFORM="$(DEVELOPER_DIR)/Platforms ...

  2. Build FFmpeg for iOS

    FFmpeg Build Instructions MAC 10.8 or better Copy ffmpeg-2.0.tar.bz2 (https://ffmpeg.org/releases/ff ...

  3. webservice 第一节 .net SoapHeader验证

    在工作中经常用到webservice,在.net 开发中经常用到webservice,在java开发经常用到cxf. 今天闲置没事就介绍下 .net webservice中常用到 soapheader ...

  4. MFC中菜单变灰的问题

    MFC中菜单变灰 方法1:有UpdateCmdUI句柄时 定义一个BOOL变量m_b来标志菜单项是否有效, 该菜单项响应UPDATE_COMMAND_UI消息,在消息处理函数中pCmdUI->E ...

  5. Centos 64位 Install certificate on apache 即走https协议

    Centos 64位 Install certificate on apache 即走https协议 一: 先要apache 请求ssl证书的csr 一下是步骤: 重要注意事项 An Importan ...

  6. Union 与 Union all 区别

    原创,请园长不要删 Sql查询统计时,很多时候用到了union 和 union all,union与union all的区别就是联合查询的时候union会去重,union all不会去重.本人用uni ...

  7. Kendo UI开发教程(6): Kendo DataSource 概述

    Kendo 的数据源支持本地数据源(JavaScript 对象数组),或者远程数据源(XML, JSON, JSONP),支持CRUD操作(创建,读取,更新和删除操作),并支持排序,分页,过滤,分组和 ...

  8. Hackers’ Crackdown-----UVA11825-----DP+状态压缩

    题目地址:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  9. PB导出规定格式DBF文件

    最近在做一个给卫计委做数据上报的数据接口,接口要求使用奇葩的dBase 3数据库存储上报数据,忙活了几天总算搞好了,使用开发工具为powerbuild 12,222个字段的上报数据表生成DBF文件,写 ...

  10. github 自学文档 希望可以给初学的人一些帮助

    一 .git的安装 windows下面的安装:https://git-for-windows.github.io  从这里下载完全无脑安装. 安装完成后,在开始菜单里找到"Git" ...