【发布时间】:2013-10-22 07:20:38
【问题描述】:
我们都知道在多线程环境中处理 .NET 事件时的问题。 其中之一是当我们尝试调用事件而不复制到局部变量时:
if (MyEvent != null)
MyEvent(this, EventArgs.Empty);
在这种情况下,如果在一个线程检查 MyEvent != null 之后,另一个线程取消订阅事件处理程序,我们可以获得竞争条件。 (然后 MyEvent 试图触发和操作.. NullRefException)
解决方案(由 J.Richter 提出)是将事件处理程序复制到局部变量:
var handler = MyEvent;
if (handler != null)
handler(this, EventArgs.Empty);
这很好用,因为
Delegates are immutable; once created, the invocation list of a delegate does not change.
但据我所知AMD64 JIT does some optimizations 可以忽略本地副本并读取事件处理程序的实际值。 (一篇文章很旧,但我找不到任何关于此类问题的实际信息)。
那么,CLR JIT 在这种情况下实际上是如何工作的?会不会有 NullReferenceException?
【问题讨论】:
-
IMO 事件完全不适合多线程环境。
-
@spender 你为什么会这样建议?如果您正确使用事件,事件在线程环境中仍然非常有用。许多线程组件完全基于事件...
标签: c# .net multithreading clr jit