当前位置: 首页 > news >正文

.NET/C# 利用 Walterlv.WeakEvents 高性能地定义和使用弱事件

弱引用是 .NET 引入的概念,可以用来协助解决内存泄漏问题。然而事件也可能带来内存泄漏问题,是否有弱事件机制可以使用呢?.NET 没有自带的弱事件机制,但其中的一个子集 WPF 带了。然而我们不是什么项目都能引用 WPF 框架类库的。

本文介绍 Walterlv.WeakEvents 库来定义和使用弱事件。


本文内容

    • 下载安装 Walterlv.WeakEvents
    • 定义弱事件
    • 使用弱事件

系列博客:

  • .NET/C# 利用 Walterlv.WeakEvents 高性能地定义和使用弱事件
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地中转一个自定义的弱事件(可让任意 CLR 事件成为弱事件)
  • .NET 设计一套高性能的弱事件机制

下载安装 Walterlv.WeakEvents

在你需要做弱事件的项目中安装 NuGet 包:

  • Walterlv.WeakEvents

定义弱事件

现在,定义弱事件就不能直接写 event EventHandler Bar 了,要像下面这样写:

using System;
using Walterlv.WeakEvents;

namespace Walterlv.Demo
{
    public class Foo
    {
        private readonly WeakEvent<EventArgs> _bar = new WeakEvent<EventArgs>();

        public event EventHandler Bar
        {
            add => _bar.Add(value, value.Invoke);
            remove => _bar.Remove(value);
        }

        private void OnBar() => _bar.Invoke(this, EventArgs.Empty);
    }
}

使用弱事件

对于弱事件的使用,就跟以前任何其他正常事件一样了,直接 +=-=

这样,如果我有一个 A 类的实例 a,订阅了以上 FooBar 事件,那么当 a 脱离作用范围后,将可以被垃圾回收机制回收。而如果不这么做,Foo 将始终保留对 a 实例的引用,这将阻止垃圾回收。


我的博客会首发于 https://blog.walterlv.com/,而 CSDN 会从其中精选发布,但是一旦发布了就很少更新。

如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。

知识共享许可协议

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://walterlv.blog.csdn.net/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。

相关文章:

  • WPF 程序如何跨窗口/跨进程设置控件焦点
  • 使用 SetParent 制作父子窗口的时候,如何设置子窗口的窗口样式以避免抢走父窗口的焦点
  • WPF 程序如何移动焦点到其他控件
  • EFI 分区/恢复分区不可删除?你需要使用命令行了(配合鼠标操作)
  • EFI 分区/恢复分区不可删除?你需要使用命令行了(全命令行操作)
  • 使用傲梅分区助手无损合并分区,无损调整分区大小
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • Windows 系统上用 .NET/C# 查找所有窗口,并获得窗口的标题、位置、尺寸、最小化、可见性等各种状态
  • 直击本质:WPF 框架是如何实现模态窗口的
  • 什么是模态窗口?本文带你了解模态窗口的本质
  • 使用 .editorconfig 配置 .NET/C# 项目的代码分析规则的严重程度
  • 如何在 .NET 项目中开启不安全代码(以便启用 unsafe fixed 等关键字)
  • WPF 高性能位图渲染 WriteableBitmap 及其高性能用法示例
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • 使用 Direct3D11 的 OpenSharedResource 方法渲染来自其他进程/设备的共享资源(SharedHandle)
  • 分享的文章《人生如棋》
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • css系列之关于字体的事
  • Laravel核心解读--Facades
  • node入门
  • storm drpc实例
  • 构造函数(constructor)与原型链(prototype)关系
  • 简单易用的leetcode开发测试工具(npm)
  • 数组大概知多少
  • 思否第一天
  • 协程
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • #QT(TCP网络编程-服务端)
  • #我与Java虚拟机的故事#连载10: 如何在阿里、腾讯、百度、及字节跳动等公司面试中脱颖而出...
  • (01)ORB-SLAM2源码无死角解析-(66) BA优化(g2o)→闭环线程:Optimizer::GlobalBundleAdjustemnt→全局优化
  • (Java)【深基9.例1】选举学生会
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • (Redis使用系列) Springboot 使用redis实现接口Api限流 十
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (十)DDRC架构组成、效率Efficiency及功能实现
  • (五)c52学习之旅-静态数码管
  • .NET 8.0 发布到 IIS
  • .net redis定时_一场由fork引发的超时,让我们重新探讨了Redis的抖动问题
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .pop ----remove 删除
  • .sdf和.msp文件读取
  • @RunWith注解作用
  • [ 常用工具篇 ] AntSword 蚁剑安装及使用详解
  • [] 与 [[]], -gt 与 > 的比较
  • []新浪博客如何插入代码(其他博客应该也可以)
  • [17]JAVAEE-HTTP协议
  • [C++] new和delete
  • [C++]unordered系列关联式容器
  • [CF482B]Interesting Array
  • [CTSC2014]企鹅QQ
  • [EFI]Atermiter X99 Turbo D4 E5-2630v3电脑 Hackintosh 黑苹果efi引导文件
  • [FxCop.设计规则]8. 也许参数类型应该是基类型
  • [LeetCode] 197. 上升的温度