1. 程式人生 > >線程安全的事件調用方式

線程安全的事件調用方式

方式 vol pro public bsp 之前 != 註冊 問題

通常事件調用方式為

//版本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編譯器一般不會這麽做)

線程安全的事件調用方式