帶有空檢查的事件調度的多線程安全
在基於事件的編程中,事件允許不同的對象進行通信並對某些事件做出反應。在事件處理程序委託上使用空檢查來分派事件是一種常見的做法,如下所示:
public event EventHandler SomeEvent; ... { .... if(SomeEvent!=null)SomeEvent(); }
但是,在多線程環境中,存在潛在的競爭條件,其中另一個線程可以修改事件的呼叫清單在空檢查和呼叫之間。這可能會導致異常或不正確的行為。
解決多執行緒問題
為了緩解這種情況,建議將事件處理程序委託分配給事件中的局部變數調度方法,如下所示:
protected virtual void OnSomeEvent(EventArgs args) { EventHandler ev = SomeEvent; if (ev != null) ev(this, args); }
藉由這樣做,任何後續對SomeEvent 事件處理程序清單的修改都不會影響儲存在ev 變數中的副本。這確保了即使事件處理程序清單同時發生變化,事件也會被正確地呼叫。
需要注意的是,該解決方案僅解決多執行緒事件處理的一個面向。它沒有完全考慮已失效的事件處理程序或複製後訂閱的事件處理程序。有關該領域最佳實踐的綜合指南,請參閱 Eric Lippert 的部落格文章和 StackOverflow 上有關該主題的討論。
以上是空檢查派發事件時如何保證多執行緒安全?的詳細內容。更多資訊請關注PHP中文網其他相關文章!