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>的更多相关文章

  1. php blowfish加密解密具体算法

    PHP Blowfish 算法的加密解密,供大家参考,具体内容如下<?php/*** php blowfish 算法* Class blowfish*/class blowfish{/*** b ...

  2. “盛大游戏杯”第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 描述 在一个矩形的灰度图像上,每个 ...

  3. [Spark內核] 第41课:Checkpoint彻底解密:Checkpoint的运行原理和源码实现彻底详解

    本课主题 Checkpoint 运行原理图 Checkpoint 源码解析 引言 Checkpoint 到底是什么和需要用 Checkpoint 解决什么问题: Spark 在生产环境下经常会面临 T ...

  4. 3DES加解密 C语言

    3DES(或称为Triple DES),它相当于是对每个数据块应用三次DES加密算法.3*8字节密钥. 设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,P代表明文,C代 ...

  5. js_md5加密和base64的加密解密

    1.最近有些人在爬我们公司的数据,然有了这个md5加密的小需求.为什么叫小需求呢?嗯,之前没做过,会以为很复杂. 其实,是想多了. 2.前端md5加密,其实也并不是安全的,因为代码是可见的.也就是说, ...

  6. 实用工具类--第三方开源--Lazy

    下载地址 :https://github.com/ddwhan0123/Lazy 工具 描述 AnimationUtils 动画工具类 AppUtils APP相关信息工具类 AssetDatabas ...

  7. CTF中编码与加解密总结

    CTF中那些脑洞大开的编码和加密 转自:https://www.cnblogs.com/mq0036/p/6544055.html 0x00 前言 正文开始之前先闲扯几句吧,玩CTF的小伙伴也许会遇到 ...

  8. CTF密码学常见加解密总结

    CTF密码学常见加解密总结 2018年03月10日 19:35:06 adversity` 本文链接:https://blog.csdn.net/qq_40836553/article/details ...

  9. PHP的学习--RSA加密解密

    PHP服务端与客户端交互或者提供开放API时,通常需要对敏感的数据进行加密,这时候rsa非对称加密就能派上用处了. 举个通俗易懂的例子,假设我们再登录一个网站,发送账号和密码,请求被拦截了. 密码没加 ...

随机推荐

  1. MySQL一个简单的存储过程demo

    使用的工具是Navicat for MySQL. 首先创建一个学生表 mysql) ) ) auto_increment,age ) ) not null,primary key(s_no)); Qu ...

  2. sql连接查询中on筛选与where筛选的区别

    sql查询这个东西, 要说它简单, 可以很简单, 通常情况下只需使用增删查改配合编程语言的逻辑表达能力,就能实现所有功能. 但是增删查改并不能代表sql语句的所有, 完整的sql功能会另人望而生畏. ...

  3. Android学习探索之运用MVP设计模式实现项目解耦

    前言: 一直致力于提高开发效率降低项目耦合,今天想抽空学习一下MVP架构设计模式,学习一下如何运用到项目中. MVP架构设计模式 MVP模式是一种架构设计模式,也是一种经典的界面模式.MVP中的M代表 ...

  4. redis 数据库实现

    redis 数据库实现 数据库的 server 端和 client 端 server 端 数据库在 server 端的存储 // redisServer 结构 struct redisServer { ...

  5. SpringMVC4+MyBatis+SQL Server2014 基于SqlSession实现读写分离(也可以实现主从分离)

    前言 上篇文章我觉的使用拦截器虽然方便快捷,但是在使用读串还是写串上你无法控制,我更希望我们像jdbc那样可以手动控制我使用读写串,那么这篇则在sqlsession的基础上实现读写分离, 这种方式则需 ...

  6. 深入tornado中的Configurable

    Configurable十分重要! 位于tornado.util文件中,它是一个工厂类. 我们暂且称这个类为 配置类 . 我们暂且约定:该类的子类称之为 直属配置子类 , 该类的孙类.重孙类……称之为 ...

  7. caffe:使用C++来提取任意一张图片的特征(从内存读取数据)

    0x00 关于使用C++接口来提取特征,caffe官方提供了一个extract_features.cpp的例程,但是这个文件的输入是blob数据,即使输入层使用的是ImageData,也需要在depl ...

  8. 全易通人事考勤工资验厂管理系统软件创建连接SQL2000数据库的操作方法和说明

    全易通人事考勤工资验厂管理系统软件创建连接SQL2000数据库的操作方法和说明.全易通人事考勤工资验厂管理系统软件,有2种数据库,一个是ACCESS,另一个是SQL.不过由于ACCESS数据库比较小, ...

  9. CI Weekly #18 | flow.ci iOS 最佳实践出炉,正式支持 Git@OSC 构建

    如大家所期待,flow.ci 现已支持开源中国的代码仓库 - 码云,可以直接构建 Git@OSC 的项目了,点击创建项目-选择代码仓库-选择码云-绑定 OSChina 账户-选择要构建项目,教程看这里 ...

  10. PHP的学习记录

    这是我的第一次写博客,是一个PHP的初学者,刚刚开始之前是一点儿的都不懂,现在开始通过买些书籍回来学习,废话少说,开始记录笔记吧. 函数:函数的英文名为function,也就是功能的意思,在自定义函数 ...