.NET中调用委托前必须检查值是否为NULL,否者会引发一空引用异常。
但对于多线程环境,此种检查任然不够,因为访问委托时可能发生竞态条件。
public class Publisher
{
public event EventHandler MyEvent;
public void Fire()
{
//将委托传入一个方法,目的为了拷贝委托,因此方法中检查调用的只是某一临时变量,而非原来的委托
//委托为一不可变对象,对委托所做任何改变,都将导致在堆上创建一新委托
Fire(MyEvent);
}
//为避免JIT优化代码,使用内联,直接使用委托对象,导致竞态条件
//使用该特性,通知JIT在任何情况下,方法参数都不要内联
[MethodImpl(MethodImplOptions.NoInlining)]
private void Fire(EventHandler handler)
{
if(handler != null)
{
handler(this, EventArgs.Empty);
}
}
}