0

0

C#怎么使用Lazy延迟加载_C#如何优化大对象的初始化速度【详解】

穿越時空

穿越時空

发布时间:2026-03-12 16:58:36

|

270人浏览过

|

来源于php中文网

原创

Lazy 是延迟初始化机制,解决“何时初始化”而非“初始化快慢”,适用于构造开销大且非必用的对象;误用会导致重复初始化、额外开销或失去延迟意义。

c#怎么使用lazy延迟加载_c#如何优化大对象的初始化速度【详解】

Lazy 不是“懒”,是“等真要用时再造”

它不解决初始化逻辑本身的速度,只解决「要不要初始化」的时机问题。如果你的对象构造开销大、又不是每次都会用到,Lazy<t></t> 才值得上——否则加了反而多一层委托调用和线程同步开销。

常见错误现象:Lazy<t></t> 实例一创建就触发初始化(比如误用了 Value 属性在构造后立刻读取),或者多个线程反复初始化(没设 isThreadSafe = true)。

  • 默认构造的 Lazy<t></t> 是线程安全的,但会带来 Monitor.Enter 开销;如果确定单线程使用,可用 new Lazy<t>(func, isThreadSafe: false)</t>
  • 不要把 Lazy<t></t> 当缓存用:它只保证初始化一次,不处理后续值变更;要响应式更新得换 IObservable<t></t> 或手动重置
  • 初始化函数里抛异常?Lazy<t>.Value</t> 第二次读会直接 rethrow 原异常,不是重新执行——这点常被忽略

别在属性里无脑套 new Lazy()

写成 public Lazy<list>> Items => new Lazy<list>>(LoadItems);</list></list> 看似延迟,实则每次 get 都新建一个 Lazy<t></t> 实例,完全失去意义。

正确做法是字段级缓存:

private readonly Lazy<List<string>> _items = new Lazy<List<string>>(LoadItems);

public List<string> Items => _items.Value;

使用场景:ASP.NET Core 的 Controller 中依赖注入大配置对象、WinForms 启动时加载大量 UI 资源、单元测试中模拟耗时外部服务。

  • 字段必须是 readonly,否则可能被意外重赋值,导致多次初始化
  • 如果 LoadItems 依赖实例状态(比如 this._config),确保该状态在 Lazy<t></t> 构造前已就绪
  • 别对值类型(如 intDateTime)用 Lazy<t></t>——堆分配+同步开销远超收益

async 场景下 Lazy 不行,得用 Lazy>

Lazy<t></t> 的工厂函数不能是 async,因为 Func<t></t> 不接受 Task<t></t> 返回值。强行 await 会导致同步阻塞或死锁(尤其在 UI/ASP.NET 同步上下文里)。

Krea AI
Krea AI

多功能的一站式AI图像生成和编辑平台

下载

正确解法是把异步延迟封装进 Lazy<task>></task>

private readonly Lazy<Task<List<string>>> _data = new Lazy<Task<List<string>>>(LoadDataAsync);

public async Task<List<string>> GetDataAsync() => await _data.Value;

注意:此时 _data.Value 返回的是同一个 Task 实例,不会重复发起请求——这是 Lazy<task>></task> 的关键价值。

  • 别用 Task.Run(() => new Lazy<t>(...))</t>,这等于绕路启动线程,还丢掉上下文捕获能力
  • 如果需要取消支持,工厂函数里得接收 CancellationToken,并传给内部 await 调用
  • 异常处理逻辑和同步版一致:第一次 await 失败,后续 await 都直接 throw 同一个 AggregateException

替代方案比 Lazy 更轻量的情况

当对象构造只是稍慢、且确定只在某个方法内用一次,直接用局部变量 + 提前 return 更干净:

public string GetReport() {
    if (!_shouldGenerateReport) return string.Empty;
    var data = ExpensiveLoad(); // 就这儿造,不用包 Lazy
    return Format(data);
}

性能影响明显:空的 Lazy<t></t> 实例约 24 字节(.NET 6+),而一次判断 + 局部变量几乎零成本。

  • 配置类、DTO、简单集合初始化,通常不值得上 Lazy<t></t>
  • Unity 或 AOT 编译环境(如 iOS)要注意:Lazy<t></t> 内部用反射生成委托,可能触发 IL trimming 问题
  • 调试时看 Lazy<t></t> 字段值,VS 默认显示 IsValueCreated = false,容易误判为“没生效”,其实只是还没触发
事情说清了就结束。真正卡顿的地方,往往不在“怎么延迟”,而在“为什么非得造这个大对象”。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1010

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

611

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

334

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

235

2025.08.29

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

443

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

605

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

765

2023.08.10

unity是什么软件
unity是什么软件

Unity是一款强大而易于使用的游戏开发引擎,它为开发者提供了一套完整的工具和技术,使他们能够创建各种类型的游戏和交互式内容。本专题为大家提供unity相关的各种文章、以及下载和课程。

240

2023.08.09

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 11.1万人学习

C 教程
C 教程

共75课时 | 5.4万人学习

C++教程
C++教程

共115课时 | 21.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号