【发布时间】:2013-04-23 06:49:18
【问题描述】:
我有关于此 MSDN 杂志article 的问题。
阅读简介正如我刚刚解释的那样,编译器有时会熔断 多读合二为一。编译器还可以拆分单个读取 成多读。在 .NET Framework 4.5 中,阅读介绍是 远不如读取消除常见,并且仅在非常罕见的情况下发生, 具体情况。但是,有时确实会发生。
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;
}
}
如果您检查 PrintObj 方法,看起来 obj 值将 在 obj.ToString 表达式中永远不要为空。然而,那一行 代码实际上可能会抛出 NullReferenceException。 CLR JIT 可能 编译 PrintObj 方法,就好像它是这样写的:
void PrintObj() {
if (_obj != null) {
Console.WriteLine(_obj.ToString());
}
}
但这不就是一种处理事件的模式吗?!
void RaiseEvent()
{
var myEvent = MyEvent;
if (myEvent != null)
{
myEvent(this, EventArgs.Empty);
}
}
我在这里错过了什么重要的事情吗?
【问题讨论】:
-
this question 涵盖了类似的基础,指出在正常使用中,您不太可能真正遇到问题(因为 JIT 团队知道这种模式,他们不太可能引入优化并打破它),还有一个answer 显示了一种防止它发生的方法。
-
这些是可怕的东西,会在晚上发生碰撞。该代码的非优化版本也不是没有问题的。您仍在触发侦听器可能已经取消订阅的事件。这也不会经常有好的结果。最好的指导很简单:不要这样做。
标签: c# .net multithreading events