解密Lazy<T>
1.Lazy<T>的使用
无意间看到一段代码,在创建对象的时候使用了Lazy,顾名思义Lazy肯定是延迟加载,那么它具体是如何创建对象,什么时候创建对象了? 先看这段示列代码:
public class OrderController : Controller
{
private readonly Lazy<OrderService> _orderSrv = new Lazy<OrderService>(); public ActionResult CreateOrder(OrderModel model)
{
var result = _orderSrv.Value.CreateOrder(model);
return Json(result);
}
}
使用非常简单,把 OrderService 放到Lazy<T> 中,然后 _orderSrv.Value 的时候才真正创建OrderService 对象。
那么问题来,是不是每次_orderSrv.Value 一下,就创建一个对象了? 想到这里,程序猿基本的条件反射,对着Lazy按下F12。
构造函数中,有个isThreadSafe的参数,默认是true。ok,参考了msdn的例子,我们来测试看看。
static void Main(string[] args)
{
Lazy<int> number = new Lazy<int>(() => Thread.CurrentThread.ManagedThreadId); Thread t1 = new Thread(() =>
Console.WriteLine("number on t1 = {0} ThreadID = {1}"
,number.Value, Thread.CurrentThread.ManagedThreadId));
t1.Start(); Thread t2 = new Thread(() =>
Console.WriteLine("number on t2 = {0} ThreadID = {1}"
,number.Value, Thread.CurrentThread.ManagedThreadId));
t2.Start(); Thread t3 = new Thread(() =>
Console.WriteLine("number on t3 = {0} ThreadID = {1}"
, number.Value,Thread.CurrentThread.ManagedThreadId));
t3.Start(); Console.ReadLine(); }
结果:
很明显,number 被ID=10的线程初始化后,值一直没有改变,说明三个线程用的是同一个实例。
再试试 isThreadSafe=false 。
Lazy<int> number = new Lazy<int>(() => Thread.CurrentThread.ManagedThreadId, false);
结果(1):
number实例被ID=11的线程使用后,其他线程就不能再正确使用了,number.value=0 说明 int并没有被赋值。
结果(2):
直接报错了,我的理解是,Lazy此时并不支持多线程并发。
2.Lazy<T> 的 valueFactory
继续在f12中找到解释:
结合我们上面的例子,可分析出,valueFactory是个委托,number.value的时候就是由valueFactory来创建这个实例。
看到这里,我们发现Lazy<T> 还是很强大的,可以用T的默认构造函数来创建实例也可以用指定的Func来创建实例,而且还支持多线程安全。
3.Lazy<T>的工作原理
用反编译插件看看代码:
static Lazy()
{
Lazy<T>.ALREADY_INVOKED_SENTINEL = () => default(T);
Lazy<T>.PUBLICATION_ONLY_SENTINEL = new object();
}
[__DynamicallyInvokable]
public Lazy(Func<T> valueFactory, LazyThreadSafetyMode mode)
{
if (valueFactory == null)
{
throw new ArgumentNullException("valueFactory");
}
this.m_threadSafeObj = Lazy<T>.GetObjectFromMode(mode);
this.m_valueFactory = valueFactory;
}
看到 default(T) 和 this.m_valueFactory = valueFactory 大概也知道是如何创建实例了吧。
本文博客园地址:http://www.cnblogs.com/struggle999/p/6917067.html
解密Lazy<T>的更多相关文章
- php blowfish加密解密具体算法
PHP Blowfish 算法的加密解密,供大家参考,具体内容如下<?php/*** php blowfish 算法* Class blowfish*/class blowfish{/*** b ...
- “盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛题解&&源码【A,水,B,水,C,水,D,快速幂,E,优先队列,F,暴力,G,贪心+排序,H,STL乱搞,I,尼姆博弈,J,差分dp,K,二分+排序,L,矩阵快速幂,M,线段树区间更新+Lazy思想,N,超级快速幂+扩展欧里几德,O,BFS】
黑白图像直方图 发布时间: 2017年7月9日 18:30 最后更新: 2017年7月10日 21:08 时间限制: 1000ms 内存限制: 128M 描述 在一个矩形的灰度图像上,每个 ...
- [Spark內核] 第41课:Checkpoint彻底解密:Checkpoint的运行原理和源码实现彻底详解
本课主题 Checkpoint 运行原理图 Checkpoint 源码解析 引言 Checkpoint 到底是什么和需要用 Checkpoint 解决什么问题: Spark 在生产环境下经常会面临 T ...
- 3DES加解密 C语言
3DES(或称为Triple DES),它相当于是对每个数据块应用三次DES加密算法.3*8字节密钥. 设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,P代表明文,C代 ...
- js_md5加密和base64的加密解密
1.最近有些人在爬我们公司的数据,然有了这个md5加密的小需求.为什么叫小需求呢?嗯,之前没做过,会以为很复杂. 其实,是想多了. 2.前端md5加密,其实也并不是安全的,因为代码是可见的.也就是说, ...
- 实用工具类--第三方开源--Lazy
下载地址 :https://github.com/ddwhan0123/Lazy 工具 描述 AnimationUtils 动画工具类 AppUtils APP相关信息工具类 AssetDatabas ...
- CTF中编码与加解密总结
CTF中那些脑洞大开的编码和加密 转自:https://www.cnblogs.com/mq0036/p/6544055.html 0x00 前言 正文开始之前先闲扯几句吧,玩CTF的小伙伴也许会遇到 ...
- CTF密码学常见加解密总结
CTF密码学常见加解密总结 2018年03月10日 19:35:06 adversity` 本文链接:https://blog.csdn.net/qq_40836553/article/details ...
- PHP的学习--RSA加密解密
PHP服务端与客户端交互或者提供开放API时,通常需要对敏感的数据进行加密,这时候rsa非对称加密就能派上用处了. 举个通俗易懂的例子,假设我们再登录一个网站,发送账号和密码,请求被拦截了. 密码没加 ...
随机推荐
- Sencha+cordova 构造 华丽手机程序,并讲讲,在商用项目中经常用到的cordova插件(一)
采用 Sencha Architect 3 ,编辑设计,我只想说一个结论,jq能搞的 Sencha touch也能做到(只是 设计思路 更面向对象,学习知识量大点而已 ,不理解 MVC 就不用选了), ...
- 《Effective C#》读书笔记-1.C# 语言习惯-1.使用属性而不是可访问的数据成员
思维导图: 大纲: 1.使用属性而不是可访问的数据成员 属性 指定不同的访问权限 隐式属性降低了声明属性的工作量 允许将数据成员作为公共接口的一部分暴露 ...
- vue 调用高德地图
一. vue-amap,一个基于 Vue 2.x 和高德地图的地图组件 https://elemefe.github.io/vue-amap/#/ 这个就不细说了,按照其文档,就能够安装下来. 二. ...
- 【WPF】学习笔记(一)——做一个简单的电子签名板
参加实习(WPF)已经有两个多周的时间了,踩了一些坑,也算积累了一些小东西,准备慢慢拿出来分享一下.(●'◡'●) 这次呢就讲讲一个简单的电子签名板的实现. 先上张图(PS:字写得比较丑,不要太在意哈 ...
- 如何使用python生成xml
最近要用python生成一个xml格式的文件.因为有一些内容是中文,原来的xml文件中使用了CDATA 的部分. 而之前的python程序所用的库中没有 创建这个区域的方法.无奈研究了大半天. 最后用 ...
- nginx与apache配合反向代理技术2
注意,上次我们只是简单的在同一台服务器模拟搭建了一个新的http服务器(启用了8080端口),使用的是apache,从而模拟了多台服务器实现的Nginx反向代理,通过Nginx向上游代理服务器发送请求 ...
- VS2017使用 SQL Localdb问题两则
VS2017使用 SQL Localdb问题两则 来博客园不算短了,总是索取者.最近使用VS2017,遇到一些问题,在解决时总是找不到拿来就能用的解决方案,在多方寻找,自行探索下,总算圆满解决,在这 ...
- poj3160强连通分量加dfs
After retirement as contestant from WHU ACM Team, flymouse volunteered to do the odds and ends such ...
- ACE框架 同步原语设计
ACE框架常用的同步机制设计成统一的原语接口.同步原语使用系统平台(操作系统,多线程库)提供的同步原语,并为系统平台不提供的同步原语提供模拟实现.ACE框架使用了外观模式和适配器分两层,将同步原语统一 ...
- redis 实例2 构建文章投票网站后端
redis 实例2 构建文章投票网站后端 1.限制条件 一.如果网站获得200张支持票,那么这篇文章被设置成有趣的文章 二.如果网站发布的文章中有一定数量被认定为有趣的文章,那么这些文章需要被设置 ...