C# Lazy Loading
前言
按需加载对象延迟加载实际是推迟进行创建对象,直到对其调用后才进行创建初始化,延迟(懒加载)的好处是提高系统性能,避免不必要的计算以及不必要的资源浪费。
常规有这些情况:
- 对象创建成本高且程序可能不会使用它。 例如,假定内存中有具有 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的更多相关文章
- Angular2+typescript+webpack2(支持aot, tree shaking, lazy loading)
概述 Angular2官方推荐的应该是使用systemjs加载, 但是当我使用到它的tree shaking的时候,发现如果使用systemjs+rollup,只能打包成一个文件,然后lazy loa ...
- Lazyr.js – 延迟加载图片(Lazy Loading)
Lazyr.js 是一个小的.快速的.现代的.相互间无依赖的图片延迟加载库.通过延迟加载图片,让图片出现在(或接近))视窗才加载来提高页面打开速度.这个库通过保持最少选项并最大化速度. 在线演示 ...
- Can you explain Lazy Loading?
Introduction Lazy loading is a concept where we delay the loading of the object until the point wher ...
- [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 ...
- [AngularJS] Lazy loading Angular modules with ocLazyLoad
With the ocLazyLoad you can load AngularJS modules on demand. This is very handy for runtime loading ...
- iOS swift lazy loading
Why bother lazy loading and purging pages, you ask? Well, in this example, it won't matter too much ...
- Entity Framework加载相关实体——延迟加载Lazy Loading、贪婪加载Eager Loading、显示加载Explicit Loading
Entity Framework提供了三种加载相关实体的方法:Lazy Loading,Eager Loading和Explicit Loading.首先我们先来看一下MSDN对三种加载实体方法的定义 ...
- 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 ...
- EFCore Lazy Loading + Inheritance = 干净的数据表 (二) 【献给处女座的DB First程序猿】
前言 本篇是上一篇EFCore Lazy Loading + Inheritance = 干净的数据表 (一) [献给处女座的DB First程序猿] 前菜 的续篇.这一篇才是真的为处女座的DB Fi ...
- EFCore Lazy Loading + Inheritance = 干净的数据表 (一) 【献给处女座的DB First程序猿】
前言 α角 与 β角 关于α角 与 β角的介绍,请见上文 如何用EFCore Lazy Loading实现Entity Split. 本篇会继续有关于β角的彩蛋在等着大家去发掘./斜眼笑 其他 本篇的 ...
随机推荐
- Python3.8更新特性
Python 3.8.0稳定版 部分新特性: • PEP 572,赋值+表达式 :=可以将一个表达式或者一个 if (n := len(a)) > 10:#表达式仍然用,赋值也放一起,后面不用多 ...
- Go语言入门:Hello world
本文是「vangoleo的Go语言学习笔记」系列文章之一. 官网: http://www.vangoleo.com/go/go-hello-world/ 在上一篇文章你好,Go语言中,我们对Go语言的 ...
- win10系统格式化、恢复出厂设置的操作步骤
恢复电脑出厂设置具体步骤
- 大事祭——MiserWeyte
2019.9.10 QHDYZ组建信奥集训队祭(我哪知道这个鶸学校为啥这个时候组队) 2019.9.11 成为集训队毒瘤出题人祭 2019.9.21 博客界面优化祭(终于不是白底蓝框了)“那个拿剑的就 ...
- 《Effective Java》 读书笔记(六)避免创建不必要的对象
java 有很多修饰类的属性的关键字:常用的static,final 说说final和static吧,平时在编程的时候,这两个关键字很多时候都觉得可有可无,最多的时候就是他们俩同时出现----定义常量 ...
- C++学习笔记4_new和delete
1. 默认的new和delete操作符new和delete是和c里面的mlloc和free是一样的,在堆中创建空间.堆中创建的,都要自己释放.C中void test(){ int *p=(int *) ...
- 学习笔记52_mongodb增删改查
使用use db1作为当前数据库 如果没有db1,会自动创建 使用switch db2,当前数据库切换为db2 使用show dbs,显示当前所有数据库 使用show collection ,显示当前 ...
- Java抽象类、接口、内部类
抽象类的概念: 1.Java中可以定义没有方法体的方法,还方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类: 2.如,shape类计算周长和面积的方法无法确定,那么就可以将这样 ...
- 使用vue-cookies操作cookie
1.前言 在vue中如果想要操作cookie,除了使用之前我们自己封装好的操作cookie的方法之外,我们还可以使用vue-cookies插件,这是一个简单的Vue.js插件,专门用于在vue中处理浏 ...
- 2. 彤哥说netty系列之IO的五种模型
你好,我是彤哥,本篇是netty系列的第二篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识. 简介 本文将介绍linux中的五种IO模型,同时也会介绍阻塞/非阻塞与同步/异步的区别. ...