延迟加载(Lazy Loading)是一种设计模式,它允许推迟对象的初始化,直到该对象真正被使用时才进行加载。这种技术可以帮助提高应用程序的性能和资源利用效率。
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)}");
}
}
}
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);
}
}
}
}
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;
}
}
}
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}");
}
}
}
}
Lazy<T>
处理线程安全问题延迟加载是一种强大的技术,可以显著优化应用程序的性能和资源利用。通过谨慎和有策略地应用,可以帮助开发者创建更高效、更响应迅速的应用程序。
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!