首頁 >後端開發 >C++ >在 C# 中分派事件時如何避免競爭條件?

在 C# 中分派事件時如何避免競爭條件?

Mary-Kate Olsen
Mary-Kate Olsen原創
2025-01-03 17:03:41185瀏覽

How to Avoid Race Conditions When Dispatching Events in C#?

事件調度中的競爭條件

C# 中的事件通常使用以下程式碼進行調度:

public event EventHandler SomeEvent;
...
{
    ....
    if(SomeEvent!=null)SomeEvent();
}

然而,在多執行緒環境中,這種方法可能會導致競爭條件。下面是它的發生方式:
  1. 執行緒 1 檢查 SomeEvent 是否不為 null。
  2. 執行緒 2 從 SomeEvent 移除唯一已註冊的委託。
  3. 執行緒 1 繼續執行呼叫 SomeEvent,由於呼叫清單為空而導致異常。

解決此問題並發問題,最佳實踐是在檢查null 之前將呼叫清單複製到臨時變數:
protected virtual void OnSomeEvent(EventArgs args) 
{
    EventHandler ev = SomeEvent;
    if (ev != null) ev(this, args);
}

這種方法是執行緒安全的,因為:
  • Delegate.Combine和Delegate.Remove 傳回新的委託實例而不是修改現有的委託實例。
  • .NET 中物件參考的賦值是原子。
  • 事件存取器(新增/刪除)是同步的。

透過複製調用列表,我們確保事件處理程序被調用,即使它們在複製後被刪除已採取。但是,需要注意的是,此解決方案並不能解決已失效事件處理程序的潛在狀態問題。

以上是在 C# 中分派事件時如何避免競爭條件?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn