在商务舱我有:
class Employee{
public Employee() {
m_Manager = new Lazy<Manager>( () => return myRepository.GetManager(ManagerId); );
}
public int ManagerId { get; set;}
private Lazy<Manager> m_Manager;
public Manager Manager {
get {
return m_Manager.Value;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,仅在访问Manager属性时才调用自定义存储库.现在我想在ManagerId发生变化时"重置"我的经理属性.怎么做 ?
我可以 :
class Employee{
public Employee() {
m_Manager = new Lazy<Manager>( () => return myRepository.GetManager(ManagerId); );
}
private int m_ManagerId;
public int ManagerId {
get { return m_ManagerId;}
set {
if(m_ManagerId != value)
{
m_ManagerId = value;
m_Manager = new Lazy<Manager>( () …
Run Code Online (Sandbox Code Playgroud) 从.NET 4开始,Lazy<T>
可以用来懒惰地初始化对象.直观地,懒惰初始化也可以在公共属性的getter中执行,以向调用者提供相同的功能.我想知道是否Lazy<T>
提供了后者的任何固有优势,因此应该优先考虑?
就个人而言,我觉得Lazy<>
可以迅速降低代码的可读性,但也许我刚看到它被误用了.从好的方面来说,它确保了线程的安全性,但是有很多.NET同步结构 - 也许我错了 - 让它很容易在getter中实现相同的功能.
选择最佳方法时需要注意哪些注意事项?
.NET 4.0的System.Lazy <T>类通过枚举LazyThreadSafetyMode提供三种线程安全模式,我将其概括为:
我想要一个延迟初始化的值,它遵循稍微不同的线程安全规则,即:
只有一个并发线程将尝试创建基础值.成功创建后,所有等待的线程将获得相同的值.如果在创建期间发生未处理的异常,它将在每个等待的线程上重新抛出,但它不会被缓存,后续尝试访问基础值将重新尝试创建并可能成功.
因此,与LazyThreadSafetyMode.ExecutionAndPublication的关键不同之处在于,如果创建时"先行"失败,则可以在以后重新尝试.
是否存在提供这些语义的现有(.NET 4.0)类,还是我必须自己编写?如果我自己滚动是否有一种聪明的方法可以在实现中重用现有的Lazy <T>以避免显式锁定/同步?
注意对于一个用例,假设"创建"可能很昂贵并且容易出现间歇性错误,例如从远程服务器获取大量数据.我不想进行多次并发尝试来获取数据,因为它们可能都会失败或全部成功.但是,如果它们失败了,我希望以后能够重试.