【发布时间】:2013-02-10 16:31:09
【问题描述】:
MSDN 杂志中的一个article 讨论了阅读简介的概念,并提供了一个可以被它破坏的代码示例。
public class ReadIntro {
private Object _obj = new Object();
void PrintObj() {
Object obj = _obj;
if (obj != null) {
Console.WriteLine(obj.ToString()); // May throw a NullReferenceException
}
}
void Uninitialize() {
_obj = null;
}
}
注意这个“可能会抛出 NullReferenceException”的评论 - 我从来不知道这是可能的。
所以我的问题是:如何防止阅读介绍?
我也非常感谢编译器决定引入读取的确切解释,因为文章不包含它。
【问题讨论】:
-
一个改变代码语义的 JIT 编译器,我很担心。也许这是 .NET 4.5 之前的 JIT 错误。
-
是的,这看起来绝对像 JIT 错误。事实上,无论如何我都会把它归类为错误。这篇文章有点没用——它提到了这个概念,但并没有真正说明它是如何发生的以及如何防范它。
-
@svick:即使使用多线程,这也不应该发生。没有其他线程可以影响局部变量。
-
@Konrad - _obj 变量是一个字段,而不是局部变量,这就是被攻击的那个。对事件的支持字段的访问受到 .NET
-
@KonradRudolph
Specifically, all of Microsoft’s JIT compilers respect the invariant of not introducing new reads to heap memory and therefore, caching a reference in a local variable ensures that the heap reference is accessed only once. This is not documented and, in theory, it could change, which is why you should use the fourth version. But in reality, Microsoft’s JIT compiler would never embrace a change that would break this pattern because too many applications would break. This was actually told to me by a member of Microsoft’s JIT compiler team.CLR 通过 C# 第三版第 265 页。
标签: c# .net multithreading