2009-12-10 54 views
2

假設我有一個有2個訂閱者的事件(一切發生在同一個線程中) - 一個訂閱者寫入日誌文件,另一個訂閱者顯示一個MessageBox。如何防止訂閱者發生衝突的事件?

如果MessageBox是訂閱列表中的第一個,那麼直到用戶關閉消息框後纔會寫入日誌條目。因此,日誌條目中的時間確實是消息框關閉的時間,而不是事件發生的時間。

看來最好的解決方案是讓日誌編寫器在顯示消息框的代碼之前訂閱事件。然而,在這裏類似的問題:Are event subscribers called in order of subscription?

最好的答案是永遠不依賴於訂戶的順序。那麼,如何避免衝突而不必擔心他們的訂單呢?

回答

0

編輯:

您是否在控制事件代碼?如果是這樣,你可以確保它從來沒有以一種病態的奇怪方式實現重新排序。您甚至可以將其作爲事件本身的一部分進行記錄:「此事件的處理程序始終以訂閱順序同步調用。」

說實話,我真的希望任何事件沒有去明確地記錄它。

+1

對不起 - 我指的是S. Lowe的回答 – 2009-12-10 22:53:39

+0

@ R.B。 - 好的,但同樣的邏輯適用。你是否在控制事件代碼,所以可以保證它不會攪亂事物? – 2009-12-10 23:12:03

+0

我有控制事件代碼,但不是訂閱者。 – 2009-12-10 23:21:50

2

所有的個人事件用戶都需要和其他人一起玩。正確的事情是顯示MessageBox啓動後臺線程並顯示MessageBox的事件。

+0

這是否會奏效 - 我認爲所有UI都必須來自主線程。 – ChrisF 2009-12-10 22:52:22

+0

您可以從另一個線程創建一個彈出窗口,但編輯主窗體更具挑戰性。 – 2009-12-10 22:54:48

+0

在後臺創建的消息框不會保持在最前面。 – 2009-12-10 22:57:07

1

根據所MSDN C# programming guide上的事件的文檔,事件具有以下性質(關鍵點是粗體顯示):

  • 發佈者確定何時引發事件;訂戶確定響應該事件採取了什麼行動。
  • 一個事件可以有多個訂閱者。訂戶可以處理來自多個發佈者的多個事件。
  • 沒有訂戶的事件永遠不會被提出。
  • 事件通常用於表示圖形用戶界面中的用戶操作,例如按鈕點擊或菜單選擇。
  • 當一個事件有多個訂閱者時,事件處理程序在引發事件時被同步調用。要異步調用事件,請參閱Calling Synchronous Methods Asynchronously
  • 事件可用於同步線程。
  • 在.NET Framework類庫中,事件基於EventHandler委託和EventArgs基類。

看起來最好的辦法就是在事件上使用BeginInvoke。