首页 > 代码库 > 线程安全的事件调用方式

线程安全的事件调用方式

通常事件调用方式为

//版本1

public event NewEventHandler NewEvent;
protected virtual void OnNewEvent(EventArgs e)
{
  if (NewEvent != null) NewEvent(this, e);
}

但这种方式的问题在于,在做NewEvent != null 检测之后,NewEvent事件调用之前,事件取消了注册,即NewEvent重新变成null,此时再进行调用,将会抛出异常

线程安全的做法,

//版本2

protected virtual void OnNewEvent(EventArgs e)
{
  NewEventHandler temp = Volatile.Read(ref NewEvent);
       if (temp != null) temp(this, e);
}

用一个temp变量来存储NewEvent。

Volatile.Read强迫读取NewEvent,保证复制到temp中,免得编译器将语句: NewEventHandler temp = NewEvent; 中的temp优化掉。

(但这其实一般不会发生,JIT编译器一般不会这么做)

 

线程安全的事件调用方式