C# lambda表达式参数的正确使用姿势
C#的lambda表达式的好用就不多说了,中午吃饭的时候突然想到一个以前(有年头了,难道屌丝上岁数了就回忆这个么。。。)和同事争执的坑。。
列个demo吧。。
先是一个类,这个类的对象就是为了吃堆内存用的,,
public class MemoryModel
{
public MemoryModel(int id)
{
Data = new byte[1024 * 1024];
Id = id;
}
public byte[] Data { set; get; }
public int Id { set; get; }
}
然后再来个类存放个事件
public class EventClass
{
public void Show(int m)
{
if (ShowMe != null)
ShowMe(m);
}
public event Action<int> ShowMe;
}
测试代码如下;
EventClass e = new EventClass();
int i = 0;
while (true)
{
List<MemoryModel> list = new List<MemoryModel>();
i++;
for (int j = 0; j < 100; j++)
{
var mod = new MemoryModel(i);
e.ShowMe += c =>
{
string s = mod.Id + "----" + mod.Data.Length;
Console.Write(c);
};
list.Add(mod);
}
Thread.Sleep(50);
list.Clear();
}
估计乍一看,不知所云。。不明所以。其实主要想说的是事件注册的这个lambda表达式,这块存在比较大的问题,很多人为了方便会在lambda表达式内直接使用作用域范围外的对象,比如说这个mod对象,委托也就是方法的引用,也可以说是方法的指针,运行时在执行方法时会打开栈帧,并将方法使用到的参数或参数的引用存储到该栈帧的局部变量区中,此处我定义的事件目测只有一个int类型的参数,但由于这种随意的编码就导致了我附加了两个参数,也就是mod对象。也就是说这个mod对象会被局部变量区持续引用也就发生了垃圾回收器无法对该对象进行回收了,直到EventClass对象释放为止(当然此方法内是不会的。。)。结果也就内存泄漏了。。
当然场景不只是在这个while场景下,委托内使用作用域范围外的对象都会增加那个对象的生命周期。。
对于这种情况发生的场景。。还是有一些的。。。
C# lambda表达式参数的正确使用姿势的更多相关文章
- 泛型2(lambda表达式/参数绑定)
lambda 表达式: Lambda表达式完整的声明格式如下: [capture list] (params list) mutable exception-> return type { fu ...
- ASP.NET MVC学前篇之Lambda表达式、依赖倒置
ASP.NET MVC学前篇之Lambda表达式.依赖倒置 前言 随着上篇文章的阅读,可能有的朋友会有疑问,比如(A.Method(xxx=>xx>yy);)类似于这样的函数调用语句,里面 ...
- java lambda表达式学习笔记
lambda是函数式编程(FP,functional program),在java8中引入,而C#很早之前就有了.在java中lambda表达式是'->',在C#中是‘=>’. 杜甫说:射 ...
- Java SE 8 for the Really Impatient读书笔记——Java 8 Lambda表达式
1. lambda表达式的语法 lambda表达式是一种没有名字的函数,它拥有函数体和参数. lambda表达式的语法十分简单:参数->主体.通过->来分离参数和主体. 1.1 参数 la ...
- Lambda表达式、依赖倒置
ASP.NET MVC学前篇之Lambda表达式.依赖倒置 ASP.NET MVC学前篇之Lambda表达式.依赖倒置 前言 随着上篇文章的阅读,可能有的朋友会有疑问,比如(A.Method(xxx= ...
- C#中Lambda表达式总结
在C#的语法中有一种比较特殊的写法,叫做Lambda表达式,这种表达式的写法在于你查询数据的时候直接是使用以下箭头的形式来表示查询语句的:=>.例如,我们要查找学生的List<Studen ...
- Java 8 Lambda 表达式详解
一.Java 8 Lambda 表达式了解 参考:Java 8 Lambda 表达式 | 菜鸟教程 1.1 介绍: Lambda 表达式,也可称为闭包,是推动 Java 8 发布的最重要新特性. La ...
- Python中lambda表达式的应用
lambda表达式 Python中定义了一个匿名函数叫做lambda表达式,个人理解实现的作用就是代替一些简单的函数,使得代码看上去更简洁并且可读性高.举个例子,我们有一个元组列表[(‘a’,1),( ...
- Java中lambda表达式学习
一.Lambda表达式的基础语法: Java8中引入了一个新的操作符"->"该操作符称为箭头操作符或Lambda操作符,箭头操作符将Lambda表达式拆分为两部分: 左侧:L ...
随机推荐
- vue-router 实现导航守卫(路由卫士)
路由跳转前做一些验证,比如登录验证,是网站中的普遍需求. 对此,vue-route 提供的 beforeRouteUpdate 可以方便地实现导航守卫(navigation-guards). 导航守卫 ...
- 使用IntelliJ IDEA配置Erlang开发环境
这篇文章比较详细,感谢作者,拷贝过来做个记录 ————————————————————————————————————————————————————————————————————————————— ...
- 填报表导出excel非可写单元格锁定问题
问题描述: 填报表单元格分为可写和不可写两种状态,当填报表在web上展现的时候可写单元格可以进行数据填报和修改,非可写单元格不可操作. 报表导出为excel时,润乾导出excel包默认情况下不对 ...
- BootStrap selectpicker后台动态绑定数据
项目使用BootStrap设置select时,不能动态加载,使用以下方法可以解决. //获得全部订单信息(订单ID,订单名称) function GetAllOrders(obj) { $.ajax( ...
- leetCode题解之Array Partition I
1.题目描述 2.分析 按照题目要求,主要就是对数组进行排序 3.代码 int arrayPairSum(vector<int>& nums) { ; sort( nums.beg ...
- ExpressRoute 线路预配工作流和线路状态
本页从较高层面引导你完成服务预配和路由配置工作流. 下图和相应的步骤说明了预配端到端 ExpressRoute 线路所要执行的任务. 使用 PowerShell 配置 ExpressRoute 线路. ...
- java笔记--关于多线程如何查看JVM中运行的线程
查看JVM中的线程 --如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3890280.html "谢谢-- ThreadGrou ...
- Jboss的jmx-console中查看内存和线程状态
步骤: 1.假设jboss运行在 192.168.1.100:8080 地址和端口上. 2. 浏览器中访问http://192.168.1.100:8080/,然后选择jmx-console 3.选择 ...
- 非定制UIImagePickerController的使用
非定制UIImagePickerController的使用 效果: 源码: // // ViewController.m // ImagePic // // Created by XianMingYo ...
- 一、初识MySQL数据库 二、搭建MySQL数据库(重点) 三、使用MySQL数据库 四、认识MySQL数据库的数据类型 五、操作MySQL数据库的数据(重点)
一.初识MySQL数据库 ###<1>数据库概述 1. 数据库 长期存储在计算机内的,由组织的可共享的数据集合 存储数据的仓库 文件 ...