LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

C# 延迟加载技术详解

admin
2025年2月20日 9:2 本文热度 355

什么是延迟加载?

延迟加载(Lazy Loading)是一种设计模式,它允许推迟对象的初始化,直到该对象真正被使用时才进行加载。这种技术可以帮助提高应用程序的性能和资源利用效率。

延迟加载的主要优点

  • 减少内存消耗
  • 提高应用程序启动速度
  • 按需加载资源
  • 降低系统开销

C#中的延迟加载实现方式

使用 Lazy 类

Lazy<T> 是.NET Framework 4.0引入的泛型类,提供了最简单的延迟加载实现。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AppLazy
{
    publicclass UserProfile
    {

        // 延迟加载的复杂对象  
        // ThreadSafetyMode.ExecutionAndPublication 确保线程安全  
        private Lazy<ExpensiveResource> _expensiveResource;

        public UserProfile()
        
{
            // 使用 LazyThreadSafetyMode 确保线程安全  
            _expensiveResource = new Lazy<ExpensiveResource>(
                () => new ExpensiveResource(),
                LazyThreadSafetyMode.ExecutionAndPublication
            );
        }

        public ExpensiveResource GetResource()
        
{
            // 只有在调用Value时才真正创建对象  
            return _expensiveResource.Value;
        }
    }

    publicclass ExpensiveResource
    {

        public Guid ResourceId { get; } = Guid.NewGuid();

        public ExpensiveResource()
        
{
            // 模拟复杂的初始化过程  
            Console.WriteLine($"正在初始化复杂资源 {ResourceId}...");
            Thread.Sleep(2000); // 模拟耗时操作  
            Console.WriteLine($"复杂资源 {ResourceId} 初始化完成。");
        }
    }
}
namespace AppLazy
{
    internal class Program
    {

        static void Main(string[] args)
        
{
            // 创建 UserProfile 实例  
            UserProfile userProfile = new UserProfile();

            Console.WriteLine("创建 UserProfile 实例,但尚未初始化资源...");

            // 第一次访问 ExpensiveResource  
            Console.WriteLine("第一次获取资源:");
            ExpensiveResource resource1 = userProfile.GetResource();

            // 再次访问,不会重复初始化  
            Console.WriteLine("第二次获取资源:");
            ExpensiveResource resource2 = userProfile.GetResource();

            // 验证是否是同一个实例  
            Console.WriteLine($"两次获取的资源是否是同一个实例:{object.ReferenceEquals(resource1, resource2)}");
        }
    }
}

延迟加载集合

namespace AppLazy
{
    publicclass LazyCollection
    {

        // 使用Lazy<List<T>>延迟加载集合  
        private Lazy<List<string>> _lazyItems;

        public LazyCollection()
        
{
            _lazyItems = new Lazy<List<string>>(() => LoadItems());
        }

        private List<string> LoadItems()
        {
            Console.WriteLine("正在加载数据集合...");
            // 模拟耗时的数据加载过程,比如从数据库或文件中读取  
            System.Threading.Thread.Sleep(1000); // 模拟1秒加载时间  
            returnnew List<string> { "Item1""Item2""Item3" };
        }

        public List<string> GetItems()
        {
            return _lazyItems.Value;
        }

        public static void Main(string[] args)
        
{
            LazyCollection collection = new LazyCollection();

            Console.WriteLine("创建集合实例,但尚未加载数据...");

            // 第一次访问时会触发数据加载  
            Console.WriteLine("第一次获取数据:");
            List<string> items = collection.GetItems();
            foreach (var item in items)
            {
                Console.WriteLine(item);
            }

            // 再次获取数据(不会重复加载)  
            Console.WriteLine("\n第二次获取数据:");
            items = collection.GetItems();
            foreach (var item in items)
            {
                Console.WriteLine(item);
            }
        }
    }
}

自定义延迟加载实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AppLazy
{
    // 定义一个演示用的类  
    publicclass ExpensiveResource
    {

        public Guid Id { get; privateset; }
        public DateTime CreatedAt { get; privateset; }

        public ExpensiveResource()
        
{
            Id = Guid.NewGuid();
            CreatedAt = DateTime.Now;
            Console.WriteLine($"ExpensiveResource 实例被创建,ID: {Id}");
        }

        public void DoSomething()
        
{
            Console.WriteLine($"正在使用资源 {Id}");
        }
    }
}
namespace AppLazy
{
    publicclass Program
    {

        public static void Main(string[] args)
        
{
            // 创建一个CustomLazyLoader实例  
            CustomLazyLoader<ExpensiveResource> lazyLoader = new CustomLazyLoader<ExpensiveResource>();

            Console.WriteLine("准备获取实例...");

            // 第一次调用会创建实例  
            ExpensiveResource resource1 = lazyLoader.GetInstance();
            resource1.DoSomething();

            Console.WriteLine("再次获取实例...");

            // 第二次调用会返回同一个实例  
            ExpensiveResource resource2 = lazyLoader.GetInstance();
            resource2.DoSomething();

            // 验证两次获取的是同一个实例  
            Console.WriteLine($"两次获取的实例是否相同:{ReferenceEquals(resource1, resource2)}");
        }
    }

    // 自定义延迟加载器  
    publicclass CustomLazyLoader<T> where T :new()
    {
        private T _instance;
        privatebool _isInitialized = false;
        private readonly object _lock = new object();

        public T GetInstance()
        
{
            // 线程安全的双重检查锁定模式  
            if (!_isInitialized)
            {
                lock (_lock)
                {
                    if (!_isInitialized)
                    {
                        _instance = new T();
                        _isInitialized = true;
                    }
                }
            }
            return _instance;
        }
    }
}

实际应用场景

数据库查询延迟加载

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AppLazy
{
    // 用户实体类  
    publicclass User
    {

        publicint Id { get; set; }
        publicstring Username { get; set; }
        publicstring Email { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LiteDB;

namespace AppLazy
{
    publicclass UserRepository : IDisposable
    {
        private readonly string _dbPath;
        private readonly object _lock = new object();

        public UserRepository(string dbPath = "users.db")
        
{
            _dbPath = dbPath;
        }

        private LiteDatabase CreateDatabaseConnection()
        
{
            try
            {
                // 直接使用路径,不再使用 ConnectionString  
                returnnew LiteDatabase(_dbPath);
            }
            catch (IOException ex)
            {
                Console.WriteLine($"数据库连接错误: {ex.Message}");
                throw;
            }
        }

        // 修改所有数据库操作方法  
        public List<User> FetchUsersFromDatabase()
        {
            lock (_lock)
            {
                using (var database = CreateDatabaseConnection())
                {
                    var collection = database.GetCollection<User>("users");
                    returnnew List<User>(collection.FindAll());
                }
            }
        }

        public void AddUser(User user)
        
{
            lock (_lock)
            {
                using (var database = CreateDatabaseConnection())
                {
                    var collection = database.GetCollection<User>("users");
                    collection.Insert(user);
                }
            }
        }

        public User GetUserById(int id)
        
{
            lock (_lock)
            {
                using (var database = CreateDatabaseConnection())
                {
                    var collection = database.GetCollection<User>("users");
                    return collection.FindById(id);
                }
            }
        }

        public void Dispose()
        
{
            // 如果需要额外的清理逻辑,可以在这里添加  
            GC.SuppressFinalize(this);
        }
    }

}

该文章在 2025/2/20 9:33:26 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved