透過空檢查確保事件調度中的執行緒安全
在多執行緒環境中工作時,確保執行緒不會幹擾至關重要在進行精細操作時彼此配合。其中一種操作是事件調度,它可能涉及在呼叫事件偵聽器之前檢查 null。
建議的事件調度方法涉及檢查null,如下所示:
public event EventHandler SomeEvent; ... { .... if(SomeEvent!=null)SomeEvent(); }
但是,在多個- 線程環境中,可能會出現另一個線程在空檢查和實際事件呼叫之間更改SomeEvent 的呼叫清單的情況。這可能會導致異常或意外行為。
為了解決此執行緒安全問題,常用的技術是在執行 null 檢查之前建立 SomeEvent 多播委託的副本。這是使用受保護的虛擬方法完成的,如下所示:
protected virtual void OnSomeEvent(EventArgs args) { EventHandler ev = SomeEvent; if (ev != null) ev(this, args); }
此技術可確保在進行複製後對 SomeEvent 所做的任何更改都不會影響正在呼叫的委託副本。
但是,需要注意的是,此解決方案僅解決空事件處理程序的問題。它不處理事件處理程序在新增後失效或事件處理程序在複製後訂閱的情況。
有關處理事件分派中的競爭條件的更全面的方法,請考慮使用 Interlocked.CompareExchange方法或探索 C# 6.0 的功能,例如匿名委託和線程同步原語。
以上是空檢查派發事件時如何確保執行緒安全?的詳細內容。更多資訊請關注PHP中文網其他相關文章!