在 C# 开发中,Lazy<T> 是一个非常实用的泛型类,用于实现延迟初始化(Lazy Initialization)。它允许我们在第一次访问某个属性或字段时才真正创建其值,从而提升程序性能。然而,很多初学者在使用 Lazy<T> 时会遇到一个“坑”:一旦初始化过程中抛出异常,后续的所有访问都会直接抛出同样的异常,而不会重新尝试初始化。这就是所谓的异常缓存机制。
当你使用 Lazy<T> 创建一个延迟初始化的对象时,如果初始化委托(即用于创建值的函数)在第一次执行时抛出了异常,那么这个异常会被 Lazy<T> 缓存下来。之后每次访问 .Value 属性时,都会立即抛出这个缓存的异常,而不会再尝试重新执行初始化逻辑。
这种设计是为了保证线程安全和状态一致性——一旦初始化失败,对象就处于“不可用”状态,避免在多线程环境下反复尝试可能失败的操作。
下面是一个简单的例子,展示 Lazy<T> 如何缓存异常:
using System;class Program{ static void Main() { int attempt = 0; var lazyValue = new Lazy<int>(() => { attempt++; Console.WriteLine($"尝试第 {attempt} 次初始化..."); if (attempt <= 2) throw new InvalidOperationException("初始化失败!"); return 42; }); try { Console.WriteLine(lazyValue.Value); } catch (Exception ex) { Console.WriteLine($"第一次访问异常: {ex.Message}"); } try { Console.WriteLine(lazyValue.Value); // 不会再次执行初始化逻辑! } catch (Exception ex) { Console.WriteLine($"第二次访问异常: {ex.Message}"); } }} 运行上述代码,你会发现控制台输出如下:
尝试第 1 次初始化...第一次访问异常: 初始化失败!第二次访问异常: 初始化失败! 注意:第二次访问时,“尝试第 2 次初始化...” 并没有打印出来,说明初始化逻辑根本没有再次执行。这就是 C# Lazy<T> 异常缓存 的体现。
如果你希望在初始化失败后能够重试,就不能直接使用默认的 Lazy<T>。有几种常见解决方案:
通过指定 LazyThreadSafetyMode.None,可以禁用异常缓存,但代价是失去线程安全性:
var lazyValue = new Lazy<int>(() =>{ // 可能抛出异常的逻辑}, LazyThreadSafetyMode.None); ⚠️ 注意:这种方式只适用于单线程场景,否则可能导致多次初始化或竞态条件。
更安全的做法是自己封装一个支持重试的延迟加载类。例如:
public class RetryableLazy<T>{ private readonly Func<T> _factory; private T _value; private bool _initialized = false; private readonly object _lock = new object(); public RetryableLazy(Func<T> factory) { _factory = factory; } public T Value { get { if (!_initialized) { lock (_lock) { if (!_initialized) { _value = _factory(); _initialized = true; } } } return _value; } } public void Reset() { lock (_lock) { _initialized = false; } }} 这样你就可以在捕获异常后调用 Reset() 方法,清除初始化状态,下次访问时会重新尝试。
- C# Lazy<T> 默认会缓存初始化过程中抛出的异常,这是其设计的一部分。
- 一旦发生异常,后续所有对 .Value 的访问都会立即抛出相同异常,不再执行初始化逻辑。
- 如果你需要重试机制,请不要依赖默认行为,而是采用自定义包装器或谨慎使用 LazyThreadSafetyMode.None。
- 理解 .NET Lazy 异常缓存机制 对编写健壮的延迟加载代码至关重要。
希望这篇关于 C# Lazy<T> 异常缓存 和 Lazy<T> 异常处理 的教程能帮助你避开常见陷阱,写出更可靠的 C# 代码!
本文由主机测评网于2025-12-08发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025124753.html