解密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非对称加密就能派上用处了. 举个通俗易懂的例子,假设我们再登录一个网站,发送账号和密码,请求被拦截了. 密码没加 ...
随机推荐
- struts2 之 ServletAPI
1. 在struts2中有两种方式使用SercletAPI,一种解耦方式,一种耦合方式. 2. 解耦方式就是使用ActionContext 来实现,是完全解耦 servletAPI. ActionCo ...
- 串口屏Modbus协议,串口屏的modbus协议资料,串口屏modbus通讯协议开发,串口屏之modbus协议使用技巧
串口屏Modbus协议,串口屏的modbus协议资料,串口屏modbus通讯协议开发,串口屏之modbus协议使用技巧 本例程中用51单片机作为Modbus从机,从机的设备地址为2,从机有4个寄存器, ...
- C字符串输入输出函数
下面就几个常用的字符串输入输出函数做个小小的总结TAT 使用时添加头文件:#include<stdio.h>. scanf("格式控制字符串",变量地址列表):(pri ...
- virtual box ubuntu 主机和虚拟机实现互相复制粘贴
链接:http://jingyan.baidu.com/article/574c521917db806c8d9dc18c.html 常规高级里共享粘贴板已经选中双向,(我的已经可以了复制粘贴了),如果 ...
- 【2017-04-25】winform公共控件、菜单和工具栏、Tab和无边框窗体制作
一.公共控件 1. Button 按钮 + 布局 - AutoSize 按钮尺寸自动适应里面内容的长度 - Location 位置 - Margin 控件与控件外边距 - S ...
- python自动化测试应用-番外篇--接口测试1
篇1 book-python-auto-test-番外篇--接口测试1 --lamecho辣么丑 1.1概要 大家好! 我是lamecho(辣么丑),至今<安卓a ...
- Git操作指南
请访问以下网址,很详细,今天偷个懒记录一下,之后有时间再来补全吧! https://git-scm.com/book/zh/v2
- smart beta
本文来至人大经济论坛,http://bbs.pinggu.org/thread-3151691-1-1.html 众所周知,beta在CAPM模型中衡量了相对于持有整个市场所带来的风险溢价(risk ...
- oracle修改有数据的字段属性
正常情况下,有数据时不能直接修改属性,我们可以先备份,然后清空现有数据,然后再修改和还原,过程如下: //先缓存表CREATE TABLE T_TABLE1 AS SELECT * FROM tabl ...
- 分布式锁与实现(二)——基于ZooKeeper实现
引言 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.它是一个为分布式应用提供一致性服务的软件,提 ...