编辑
2025-10-13
C#
00

目录

什么是延迟加载?
延迟加载的主要优点
C#中的延迟加载实现方式
使用 Lazy<T> 类
延迟加载集合
自定义延迟加载实现
实际应用场景
数据库查询延迟加载
调用
注意
结论

什么是延迟加载?

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

延迟加载的主要优点

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

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

使用 Lazy 类

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

C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AppLazy { public class 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; } } public class ExpensiveResource { public Guid ResourceId { get; } = Guid.NewGuid(); public ExpensiveResource() { // 模拟复杂的初始化过程 Console.WriteLine($"正在初始化复杂资源 {ResourceId}..."); Thread.Sleep(2000); // 模拟耗时操作 Console.WriteLine($"复杂资源 {ResourceId} 初始化完成。"); } } }
C#
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)}"); } } }

image.png

延迟加载集合

C#
namespace AppLazy { public class 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秒加载时间 return new 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); } } } }

image.png

自定义延迟加载实现

C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AppLazy { // 定义一个演示用的类 public class ExpensiveResource { public Guid Id { get; private set; } public DateTime CreatedAt { get; private set; } public ExpensiveResource() { Id = Guid.NewGuid(); CreatedAt = DateTime.Now; Console.WriteLine($"ExpensiveResource 实例被创建,ID: {Id}"); } public void DoSomething() { Console.WriteLine($"正在使用资源 {Id}"); } } }
C#
namespace AppLazy { public class 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)}"); } } // 自定义延迟加载器 public class CustomLazyLoader<T> where T : new() { private T _instance; private bool _isInitialized = false; private readonly object _lock = new object(); public T GetInstance() { // 线程安全的双重检查锁定模式 if (!_isInitialized) { lock (_lock) { if (!_isInitialized) { _instance = new T(); _isInitialized = true; } } } return _instance; } } }

image.png

实际应用场景

数据库查询延迟加载

C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AppLazy { // 用户实体类 public class User { public int Id { get; set; } public string Username { get; set; } public string Email { get; set; } } }
C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using LiteDB; namespace AppLazy { public class 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 return new 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"); return new 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); } } }

调用

C#
namespace AppLazy { class Program { static void Main(string[] args) { try { using (var repository = new UserRepository()) { // 添加用户 repository.AddUser(new User { Username = "john_doe", Email = "john@example.com" }); // 获取所有用户 var users = repository.FetchUsersFromDatabase(); foreach (var user in users) { Console.WriteLine($"User: {user.Username}, Email: {user.Email}"); } } } catch (Exception ex) { Console.WriteLine($"发生错误: {ex.Message}"); } } } }

image.png

注意

  • 对于计算成本高的对象使用延迟加载
  • 使用 Lazy<T> 处理线程安全问题
  • 避免在性能关键路径上使用复杂的延迟加载逻辑
  • 不要过度使用延迟加载
  • 考虑线程安全性
  • 评估初始化成本
  • 注意内存管理

结论

延迟加载是一种强大的技术,可以显著优化应用程序的性能和资源利用。通过谨慎和有策略地应用,可以帮助开发者创建更高效、更响应迅速的应用程序。

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!