标签: lazy-initialization

延迟属性初始化在 C# 中不起作用

我在使用本文档class中描述的方法初始化属性时遇到问题。

样本:

public class MyClass
{
    private Lazy<string> _lazyString;

    public MyClass()
    {
        _lazyString = new Lazy<string>(() => "hello world");
    }

    public string MyString => _lazyString.Value;
}
Run Code Online (Sandbox Code Playgroud)

当我调试时,我可以看到它_lazyString的布尔值在我访问该属性之前就已IsCreated设置为。最近的C#迭代中有什么变化吗?trueMyString

我的目标框架是netcoreapp3.1

c# lazy-initialization .net-core

2
推荐指数
1
解决办法
1791
查看次数

一旦初始化了另一个spring bean,是否有人有一个很好的初始化模式?

我的情况在我的系统中不断出现,我正在寻找一个好的代码/配置模式.我还没想出一个让我开心的东西.

该系统是基于弹簧的,几乎所有的bean都是懒惰地初始化的.有许多不同的主类使用相同的弹簧上下文.通过显式初始化几个bean,每个bean最终使用bean的不同子集,然后spring负责初始化所有依赖项.除了这一个案例,一切都很好.

问题是我的一些bean使用了一个模式(在spring配置中),我的业务bean被声明,然后另一个bean依赖于它并提供一些外围功能.然而,其他豆类的自然依赖性是前者,即商业类.

这是一个例子:

<bean id="cache">
  ...
</bean>

<bean id="cacheCuller" class="ScheduledJobBean">
  <property name="scheduler" ref="scheduler"/>
  <property name="jobDetail">
    <bean class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
      <property name="targetObject" ref="cache"/>
      <property name="targetMethod" value="removeExpiredEntries"/>
      <property name="concurrent" value="false"/>
    </bean>
  </property>
  <property name="repeatInterval" value="300000" />
</bean>
Run Code Online (Sandbox Code Playgroud)

因此,上面的第二个bean基本上会在调度程序中注册一个触发器,这将导致第一个bean上的方法被定期调用.请记住,所有这些豆都是懒惰的.如果没有活动的"缓存"客户端bean,我不想创建"cacheCuller"并初始化"缓存".我希望spring在需要注入依赖项时初始化"缓存"(这很容易)但我还希望它在之后立即初始化"cacheCuller"(这很难).

我知道我可以将调度逻辑放入"缓存"类中,但我认为将它保存在spring配置中会很好.我还想让"缓存"类不受特定于Spring的代码的影响.如果其他bean自然依赖于"cacheCuller",那么这很容易,但事实并非如此.

其他方面也出现了同样的情况,例如使用MBeanServer注册bean.我想有一个第二个bean注册业务bean,但如果它没有被用作其他(第三个)bean的依赖项,我不希望它初始化业务bean本身.

java spring lazy-initialization

1
推荐指数
1
解决办法
1492
查看次数

使用单一检查习语进行延迟初始化

在"Effective Java,Second Edition"的第71项中,为了延迟实例化实例字段,引入了双重检查惯用语和单一检查用语.

仔细检查成语

private volatile FieldType field;
FieldType getField() {
  FieldType result = field;
  if (result == null) {
    synchronized(this) {
      result == field;
      if (result == null)
        field = result = computeFieldValue();
    }
  }
  return result;
}
Run Code Online (Sandbox Code Playgroud)

单一检查成语

private volatile FieldType field;
FieldType getField() {
  FieldType result = field;
  if (result == null) {
    field = result = computeFieldValue();
  }
  return result;
}
Run Code Online (Sandbox Code Playgroud)

在Joshua所述的复核习语中,结果变量用于确保仅读取一次volatile 字段,从而提高性能.我理解这一点,但是我不明白为什么我们在单一检查习语中需要它,因为我们只读过一次字段.

java volatile lazy-initialization effective-java

1
推荐指数
1
解决办法
556
查看次数

清除内存中的惰性值

我正在写一个JRPG风格的游戏,并在YAML文件中定义我的物品/敌人等.而不是在运行时加载它们(这在Scala中被证明是一种痛苦,特别是在Android上)我决定将它们预编译为Scala对象作为惰性值.

我唯一担心的是,最终,当访问这些值时,对象将开始占用比实际需要更多的内存.

无论如何重新初始化Scala对象或将惰性值清除回默认状态?或者,有没有更好的方法来完成我在这里尝试做的事情?

scala lazy-initialization

1
推荐指数
1
解决办法
870
查看次数

在Objective-C中延迟初始化抽象属性的正确方法是什么

超级课程:

@property (strong, nonatomic) Foo *foo;
Run Code Online (Sandbox Code Playgroud)

在子类中:

- (Foo *) foo
{
     if(!super.foo) super.foo = [[Foo alloc] init];
     return super.foo;
}
Run Code Online (Sandbox Code Playgroud)

这有意义吗?拥有抽象属性甚至是个好主意?

objective-c superclass lazy-initialization

1
推荐指数
1
解决办法
961
查看次数

hibernate.enable_lazy_load_no_trans不起作用

我正在使用JPA2.1和hibernate 4.3.8,我已经配置了presistence.xml以允许延迟加载

我已经添加了

<property name="hibernate.enable_lazy_load_no_trans" value="true" />
Run Code Online (Sandbox Code Playgroud)

进入属性部分

但我仍然得到LazyInitializtionException,有什么问题?

hibernate lazy-initialization

1
推荐指数
1
解决办法
5715
查看次数

如何在初始化程序中使用lazy?

我有一个数组,我在声明时初始化它的值,如下所示:

Foo[] f = Foo[] { new Foo { y = 1 }, new Foo { y = 3 } };
Run Code Online (Sandbox Code Playgroud)

lazy该如何使用?

想象代码

Lazy<Foo[]> f = new Lazy<Foo[]> { new Foo { y = 1 }, new Foo { y = 3 } };
Run Code Online (Sandbox Code Playgroud)

.net c# lazy-initialization

1
推荐指数
1
解决办法
36
查看次数

Autofac可选/惰性依赖

如果我把Lazy放在我的对象的构造函数中,并且X没有在容器中注册,我得到了依赖项解析异常.

为什么我得到这个例外?我不喜欢它,因为我无法在运行时选择组件.用例示例:

class Controller
{
   public Controller(Lazy<A> a, Lazy<B> b) { /* (...) */ }

 Lazy<A> a;
 Lazy<B> b;

 public IActionResult Get(){
  if(someConfig)
    return Json(a.Value.Execute());
  else
    return Json(b.Value.Execute());
 }
}
Run Code Online (Sandbox Code Playgroud)

为此,我需要注册组件A和B.即使从未使用过B,我的程序也会失败.我希望B是可选的,仍然由autofac管理.

如果我有组件列表,并且只想使用一个组件,这就是更大的问题.例如:

class Controller
{
    Controller(IEnumerable<Component> components) { /* (...) */ }

    IActionResult Get()
    {
        return components.First(n => n.Name == configuredComponent).Execute();

    }

}
Run Code Online (Sandbox Code Playgroud)

我不再得到异常是没有注册的东西,但是一切都是构建的.使用起来也很尴尬.

c# autofac lazy-initialization

1
推荐指数
1
解决办法
4319
查看次数

为什么使用ExecutionAndPublication的Lazy <T>与产生IEnumerables的行为不同?

我的代码中出现了一个问题,即Lazy初始化程序的调用频率超出了我的预期.从文档中,我预计使用LazyThreadSafetyMode.ExecutionAndPublication将确保我的初始化函数只被调用过一次,例如在访问numbers.Value之后定义:

numbers = new Lazy<IEnumerable<int>>(
        () => GetNumbers(),
        LazyThreadSafetyMode.ExecutionAndPublication
    );
Run Code Online (Sandbox Code Playgroud)

但是,我发现如果初始化函数产生结果,初始化函数会被多次调用.我认为这必须延迟执行产量,但我只有模糊的意义.

题:

在下面的代码中,为什么各个初始化函数执行的次数不同?

void Main()
{
    var foo         = new foo();
    var tasks       = new List<Task>();

    for (int i = 0; i < 10; ++i) tasks.Add(Task.Run(() => {foreach (var number in foo.Numbers) Debug.WriteLine(number);})); 
    Task.WaitAll(tasks.ToArray());
    tasks.Clear();
    for (int i = 0; i < 10; ++i) tasks.Add(Task.Run(() => {foreach (var letter in foo.Letters) Debug.WriteLine(letter);})); 
    Task.WaitAll(tasks.ToArray());
}

public class foo
{
    public IEnumerable<int> Numbers => numbers.Value;
    public IEnumerable<char> Letters => letters.Value;
    readonly Lazy<IEnumerable<int>> …
Run Code Online (Sandbox Code Playgroud)

c# ienumerable lazy-initialization

1
推荐指数
1
解决办法
379
查看次数

为什么Lazy <T>不懒惰?

我有几个简单的数据库查询使用Entity Framework我想加载一次,Lazy<T>但我可以看到每次调用属性时执行查询.我尝试的变化是:

public static IEnumerable<string> Foos => new Lazy<IEnumerable<string>>(() => _db.Foos.Select(x => x.Name)).Value;

public static IEnumerable<string> Foos=> new Lazy<IEnumerable<string>>(() => _db.Foos.Select(x => x.Name).ToArray()).Value;

public static Lazy<IEnumerable<string>> Foos => new Lazy<IEnumerable<string>>(() => _db.Foos.Select(x => x.Name).ToArray());

public static IEnumerable<string> LightingEnvironments
{
    get
    {
        var lazy = new Lazy<IEnumerable<string>>(() => _db.Foos.Select(x => x.Name).ToArray());
        return lazy.Value;
    }
}
Run Code Online (Sandbox Code Playgroud)

c# lazy-initialization

1
推荐指数
1
解决办法
60
查看次数