原创

C# Lazy Loading

前言

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

常规有这些情况:

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

示例

创建用户类

 public class User
    {
        public string Name { get; set; }

        public int Age { get; set; }


        public User() {
            this.Name = "Name";
            this.Age = 0;
        }
    }

默认情况下,Lazy<T> 对象是线程安全的。 也就是说,如果构造函数没有指定线程安全性的类型,该函数创建的 Lazy<T> 对象是线程安全的。 在多线程方案中,访问线程安全 Lazy<T> 对象的 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<T> 实例正确处理争用条件(初始化时一个线程引发异常)。
  • public Lazy (LazyThreadSafetyMode mode):提供线程安全模式。
  • public Lazy (Func<T> valueFactory): lambda 表达式传递给新的 Lazy<T> 对象的构造函数。 下一次访问 Value 属性将导致新 Lazy<T> 的初始化,并且其 Value 属性此后会返回已分配给该属性的新值。

总结

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

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • asp.net core 使用HttpClientFactory Polly实现熔断降级

    在NET Core2.1后也是增加更新了很多东西,当然HttpClientFactory更新中的一部分.虽然说HttpClient这个实现了disposable...

    HueiFeng
  • ASP.NET Core 中的 ObjectPool 对象重用(一)

    对象池是一种设计模式,一个对象池包含一组已经初始化过且可以使用的对象,而可以在有需求时创建和销毁对象。池的对象可以从池中取得对象,对其进行操作处理,并在不需要时...

    HueiFeng
  • 如何为.NETCore安装汉化包智能感知

    具体不记得是在群里还是什么地方有人问过,.NETCore有没有汉化包,答案是有,目前微软已经为我们提供了.NETCore多种语言的语言包。下面看看如何安装与使用...

    HueiFeng
  • 红外接收控制灯亮灭

    先上图 功能 红外接收头接收到红外信号,控制一个灯翻转 ? 使用74HC123是因为红外接收头接收的是一连串的高低电平,,在接收到第一个电平的跳变沿的时候就控制...

    杨奉武
  • R语言可视化——数据地图应用(东三省)

    今天是一个案例应用,采用东北三省地图进行离散颜色映射,让大家感受下R语言在地理信息空间可视化方面的强大功能,同时也会对之前强调过的地图配色技巧进行应用。 加载工...

    数据小磨坊
  • 甲骨文面临的最大威胁:没有任何变化

    Larry Ellison已经步下甲骨文CEO的神坛、转而出任公司首席技术官,与此同时SafraCatz与Mark Hurd二位则顺利升任联席CEO——甲骨文官...

    静一
  • FireEye:IE再曝0day漏洞,国内暂未出现攻击

    近日,国外安全公司FireEye宣布发现新型IE 0day漏洞攻击,该漏洞影响Windows XP和Windows 7系统上的英文版本IE浏览器。不过FireE...

    安恒信息
  • 「特征工程」之零基础入门数据挖掘

    摘要:对于数据挖掘项目,本文将学习应该从哪些角度做特征工程?从哪些角度做数据清洗,如何对特征进行增删,如何使用PCA降维技术等。

    Datawhale
  • 了解了这些,轻松拿offer——Java面试之道

    synchronized是JVM层面实现的,java提供的关键字,Lock是API层面的锁。

    wangweijun
  • 2014年八大最热门的大数据工作

    大数据时代,数据过剩,人才短缺,越来越多的IT专业人士希望能够进入充满机遇的大数据领域,但是,到底哪些具体的大数据专业岗位和人才最为吃香呢?人力资源公司Kfor...

    小莹莹

扫码关注云+社区

领取腾讯云代金券