前言

按需加载对象延迟加载实际是推迟进行创建对象,直到对其调用后才进行创建初始化,延迟(懒加载)的好处是提高系统性能,避免不必要的计算以及不必要的资源浪费。

常规有这些情况:

  • 对象创建成本高且程序可能不会使用它。 例如,假定内存中有具有 Orders 属性的 Customer 对象,该对象包含大量 Order 对象,初始化这些对象需要数据库连接。 如果用户永远不要求显示 Orders 或在计算中使用该数据,则无需使用系统内存或计算周期来创建它。 通过使用 Lazy 来声明 Orders对象用于迟缓初始化,可以避免在不使用该对象时浪费系统资源。
  • 对象创建成本高,且希望将其创建推迟到其他高成本操作完成后。 例如,假定程序在启动时加载多个对象实例,但是只需立即加载其中一部分。 可以通过推迟初始化不需要的对象,直到创建所需对象,提升程序的启动性能。(来源官方)

示例

创建用户类


public class User
{
public string Name { get; set; } public int Age { get; set; } public User() {
this.Name = "Name";
this.Age = 0;
}
}

默认情况下,Lazy 对象是线程安全的。 也就是说,如果构造函数没有指定线程安全性的类型,该函数创建的 Lazy 对象是线程安全的。 在多线程方案中,访问线程安全 Lazy 对象的 Value 属性的第一个线程会为所有线程上的所有后续访问对其初始化,且所有线程共享相同的数据。 因此,哪个线程初始化对象并不重要,争用条件是良性的。


class Program
{
static void Main(string[] args)
{
Lazy<User> user = new Lazy<User>();
ThreadLocal<User> threadLocal = new ThreadLocal<User>(); if (!user.IsValueCreated)
Console.WriteLine("The object is not initialized");
Console.WriteLine(user.Value.Name);
user.Value.Name = "Name1";
user.Value.Age = 1;
Console.WriteLine(user.Value.Name);
Console.Read();
}
}
对象的线程安全性 LazyThreadSafetyMode mode 参数 布尔 isThreadSafe 参数 没有线程安全性参数
完全线程安全;一次只有一个线程尝试初始化值。 ExecutionAndPublication true 可以。
非线程安全。 None false 不适用。
完全线程安全;线程争用以初始化值。 PublicationOnly 不适用。 不适用。

其中IsValueCreated属性是个Boolean类型,我们可以通过此属性去确定当前对象有没有被初始化

调用后,进行了创建操作

再说说Lazy中几个构造函数,

  • public Lazy (bool isThreadSafe)

    isThreadSafe 的布尔参数,该方法参数用于指定是否从多线程访问 Value 属性。 如果想要仅从一个线程访问属性,则传入 false 以获取适度的性能优势。 如果想要从多线程访问属性,则传入 true 以指示 Lazy 实例正确处理争用条件(初始化时一个线程引发异常)。

  • public Lazy (LazyThreadSafetyMode mode):提供线程安全模式。

  • public Lazy (Func valueFactory)

    lambda 表达式传递给新的 Lazy 对象的构造函数。 下一次访问 Value 属性将导致新 Lazy 的初始化,并且其 Value 属性此后会返回已分配给该属性的新值。

总结

参考:https://docs.microsoft.com/en-us/dotnet/framework/performance/lazy-initialization

C# Lazy Loading的更多相关文章

  1. Angular2+typescript+webpack2(支持aot, tree shaking, lazy loading)

    概述 Angular2官方推荐的应该是使用systemjs加载, 但是当我使用到它的tree shaking的时候,发现如果使用systemjs+rollup,只能打包成一个文件,然后lazy loa ...

  2. Lazyr.js – 延迟加载图片(Lazy Loading)

    Lazyr.js 是一个小的.快速的.现代的.相互间无依赖的图片延迟加载库.通过延迟加载图片,让图片出现在(或接近))视窗才加载来提高页面打开速度.这个库通过保持最少选项并最大化速度. 在线演示    ...

  3. Can you explain Lazy Loading?

    Introduction Lazy loading is a concept where we delay the loading of the object until the point wher ...

  4. [AngularJS] Lazy Loading modules with ui-router and ocLazyLoad

    We've looked at lazy loading with ocLazyLoad previously, but what if we are using ui-router and want ...

  5. [AngularJS] Lazy loading Angular modules with ocLazyLoad

    With the ocLazyLoad you can load AngularJS modules on demand. This is very handy for runtime loading ...

  6. iOS swift lazy loading

    Why bother lazy loading and purging pages, you ask? Well, in this example, it won't matter too much ...

  7. Entity Framework加载相关实体——延迟加载Lazy Loading、贪婪加载Eager Loading、显示加载Explicit Loading

    Entity Framework提供了三种加载相关实体的方法:Lazy Loading,Eager Loading和Explicit Loading.首先我们先来看一下MSDN对三种加载实体方法的定义 ...

  8. Lazy Loading | Explicit Loading | Eager Loading in EntityFramework and EntityFramework.Core

    EntityFramework Eagerly Loading Eager loading is the process whereby a query for one type of entity ...

  9. EFCore Lazy Loading + Inheritance = 干净的数据表 (二) 【献给处女座的DB First程序猿】

    前言 本篇是上一篇EFCore Lazy Loading + Inheritance = 干净的数据表 (一) [献给处女座的DB First程序猿] 前菜 的续篇.这一篇才是真的为处女座的DB Fi ...

  10. EFCore Lazy Loading + Inheritance = 干净的数据表 (一) 【献给处女座的DB First程序猿】

    前言 α角 与 β角 关于α角 与 β角的介绍,请见上文 如何用EFCore Lazy Loading实现Entity Split. 本篇会继续有关于β角的彩蛋在等着大家去发掘./斜眼笑 其他 本篇的 ...

随机推荐

  1. Python3.8更新特性

    Python 3.8.0稳定版 部分新特性: • PEP 572,赋值+表达式 :=可以将一个表达式或者一个 if (n := len(a)) > 10:#表达式仍然用,赋值也放一起,后面不用多 ...

  2. Go语言入门:Hello world

    本文是「vangoleo的Go语言学习笔记」系列文章之一. 官网: http://www.vangoleo.com/go/go-hello-world/ 在上一篇文章你好,Go语言中,我们对Go语言的 ...

  3. win10系统格式化、恢复出厂设置的操作步骤

    恢复电脑出厂设置具体步骤

  4. 大事祭——MiserWeyte

    2019.9.10 QHDYZ组建信奥集训队祭(我哪知道这个鶸学校为啥这个时候组队) 2019.9.11 成为集训队毒瘤出题人祭 2019.9.21 博客界面优化祭(终于不是白底蓝框了)“那个拿剑的就 ...

  5. 《Effective Java》 读书笔记(六)避免创建不必要的对象

    java 有很多修饰类的属性的关键字:常用的static,final 说说final和static吧,平时在编程的时候,这两个关键字很多时候都觉得可有可无,最多的时候就是他们俩同时出现----定义常量 ...

  6. C++学习笔记4_new和delete

    1. 默认的new和delete操作符new和delete是和c里面的mlloc和free是一样的,在堆中创建空间.堆中创建的,都要自己释放.C中void test(){ int *p=(int *) ...

  7. 学习笔记52_mongodb增删改查

    使用use db1作为当前数据库 如果没有db1,会自动创建 使用switch db2,当前数据库切换为db2 使用show dbs,显示当前所有数据库 使用show collection ,显示当前 ...

  8. Java抽象类、接口、内部类

    抽象类的概念: 1.Java中可以定义没有方法体的方法,还方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类: 2.如,shape类计算周长和面积的方法无法确定,那么就可以将这样 ...

  9. 使用vue-cookies操作cookie

    1.前言 在vue中如果想要操作cookie,除了使用之前我们自己封装好的操作cookie的方法之外,我们还可以使用vue-cookies插件,这是一个简单的Vue.js插件,专门用于在vue中处理浏 ...

  10. 2. 彤哥说netty系列之IO的五种模型

    你好,我是彤哥,本篇是netty系列的第二篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识. 简介 本文将介绍linux中的五种IO模型,同时也会介绍阻塞/非阻塞与同步/异步的区别. ...