我在使用本文档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
我的情况在我的系统中不断出现,我正在寻找一个好的代码/配置模式.我还没想出一个让我开心的东西.
该系统是基于弹簧的,几乎所有的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本身.
在"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 字段,从而提高性能.我理解这一点,但是我不明白为什么我们在单一检查习语中需要它,因为我们只读过一次字段.
我正在写一个JRPG风格的游戏,并在YAML文件中定义我的物品/敌人等.而不是在运行时加载它们(这在Scala中被证明是一种痛苦,特别是在Android上)我决定将它们预编译为Scala对象作为惰性值.
我唯一担心的是,最终,当访问这些值时,对象将开始占用比实际需要更多的内存.
无论如何重新初始化Scala对象或将惰性值清除回默认状态?或者,有没有更好的方法来完成我在这里尝试做的事情?
超级课程:
@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)
这有意义吗?拥有抽象属性甚至是个好主意?
我正在使用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,有什么问题?
我有一个数组,我在声明时初始化它的值,如下所示:
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) 如果我把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)
我不再得到异常是没有注册的东西,但是一切都是构建的.使用起来也很尴尬.
我的代码中出现了一个问题,即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) 我有几个简单的数据库查询使用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# ×5
java ×2
.net ×1
.net-core ×1
autofac ×1
hibernate ×1
ienumerable ×1
objective-c ×1
scala ×1
spring ×1
superclass ×1
volatile ×1