線程安全的事件調用方式
阿新 • • 發佈:2017-06-23
方式 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編譯器一般不會這麽做)
線程安全的事件調用方式