zoukankan      html  css  js  c++  java
  • C#性能优化:延迟初始化Lazy<T>

    1. 概述

    我们创建某一个对象需要很大的消耗,而这个对象在运行过程中又不一定用到,为了避免每次运行都创建该对象,这时候延迟初始化(也叫延迟实例化)就出场了。

    延迟初始化出现于.NET 4.0,主要用于提高性能,避免浪费计算,并减少程序内存要求。也可以称为,按需加载。

    2. 基本语法

    Lazy<T> xx = new Lazy<T>();//xx代表变量名

    3. 举例实现

    首先创建一个Student类,代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace LazyTest
    {
        class Student
        {
            public Student()
            {
                this.Name = "DefaultName";
                Console.WriteLine("调用Student的构造函数");
            }
    
            public string Name { get; set; }
        }
    }

    创建一个控制台程序,代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace LazyTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                Lazy<Student> student = new Lazy<Student>();
                if (!student.IsValueCreated)
                {
                    Console.WriteLine("Student未初始化");
                }
                Console.WriteLine(student.Value.Name);
                if (student.IsValueCreated)
                {
                    Console.WriteLine("Student已经初始化");
                }
                Console.ReadKey();
            }
        }
    }

    设置断点调试后发现,在new完之后,student的IsValueCreated的值是false,value的值是null

    接着往下走,调用到Name属性时,student的IsValueCreated的值是true,value的值已经不为null了

    运行结果:

    结果可以看出,Student是在输出Name属性才进行初始化的,也就是在第一次使用时才会去初始化,这样就可以达到减少消耗的目的。

    这个例子很简单,也是Lazy<T>最基本的使用方式。我们还可以使用 Lazy<T> 的重载函数 Lazy<T> (Func<T>) 传入一个带返回值的委托来设置延迟初始化对象的属性值。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace LazyTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                Lazy<Student> student = new Lazy<Student>(() => new Student { Name = "SetName" });
                if (!student.IsValueCreated)
                {
                    Console.WriteLine("Student未初始化");
                }
                Console.WriteLine(student.Value.Name);
                if (student.IsValueCreated)
                {
                    Console.WriteLine("Student已经初始化");
                }
                Console.ReadKey();
            }
        }
    }

    运行结果:

    注:Lazy<T> 对象初始化默认是线程安全的,在多线程环境下,第一个访问 Lazy<T> 对象的 Value 属性的线程将初始化 Lazy<T> 对象,以后访问的线程都将使用第一次初始化的数据。

    4. 应用场景

    有一个对象的创建开销很大,而程序可能不会使用它。例如,假定您的程序在启动时加载若干个对象实例,但只有一些对象实例需要立即执行。通过将不必要的对象的初始化延迟到已创建必要的对象之后,可以提高程序的启动性能。

    作者:LanJerry

    出处:http://www.cnblogs.com/Lanjerry/

    您的支持是对博主最大的鼓励,感谢您的认真阅读。

    本文版权归作者所有,欢迎转载,但请保留该声明。

  • 相关阅读:
    Can't remove netstandard folder from output path (.net standard)
    website项目的reference问题
    The type exists in both DLLs
    git常用配置
    Map dependencies with code maps
    How to check HTML version of any website
    Bootstrap UI 编辑器
    网上职位要求对照
    Use of implicitly declared global variable
    ResolveUrl in external JavaScript file in asp.net project
  • 原文地址:https://www.cnblogs.com/Lanjerry/p/4835764.html
Copyright © 2011-2022 走看看