2013-03-08 67 views
3

我想創建一些自定義事件,它將始終以事件註冊的相反順序調用註冊的事件處理程序,即最先註冊的事件處理程序始終首先被調用。可能嗎?這些事件將由業務層類在特定錯誤條件下提出,其中註冊的事件處理程序可能能夠克服錯誤條件。是否可以編寫自定義事件以便在LIFO基礎上調用事件處理程序?

它是一個純技術性問題,是否可以這樣做?是否可以重寫事件鏈調用順序?語言(C#2.0,3.0,4.0的任何版本)是否支持該功能?

編輯:

的可能的使用將是錯誤報告和錯誤恢復在可能的情況。例如,Func A調用調用Func C的Func B,Func C可能遇到錯誤情況並且有一個事件。如果Func A和Func B能夠提供錯誤恢復機制,它們將註冊該事件。由於Func B更有可能具有解決錯誤的上下文,因此我想調用最新的註冊處理程序並檢查事件參數以查看錯誤是否已解決。如果是,我甚至不會打電話給其他事件處理程序。如果否,我會打電話給第二個最近註冊的處理程序,這將是來電者的來電功能,即Func A.

在大多數情況下,代碼通常以如果Func A調用Func B,然後Func B不會調用Func A,即循環調用通常不存在,並且事件處理程序的順序與函數調用的順序相同。因此,如果Func A調用Func B調用Func C,並且Func C引發「錯誤事件」,則處理該錯誤的最合適候選者是Func B的事件處理程序,隨後是Func A的事件處理程序等。

它就像堆棧跟蹤的展開並給最近的調用者函數消耗事件的機會。任何沒有。的呼叫者功能可能在那裏。

事件被任何處理程序成功使用後,將引發引發「錯誤事件」的Func C。它會檢查事件參數來確定這一點。如果沒有處理程序消耗了該事件,Func C將拋出異常。

+2

你能否提供你的實際業務問題的額外細節?通常可以通過適當使用OnEvent()方法來提升/​​降低類層次結構來實現等效功能。 – 2013-03-08 18:38:18

回答

4

是的,您可以使用MulticastDelegate.GetInvocationList()方法自己迭代事件的調用列表。像這樣:

public event EventHandler Custom; 

    protected virtual void OnCustom(EventArgs e) { 
     var handler = Custom; 
     if (handler != null) { 
      var subscribers = handler.GetInvocationList(); 
      for (int ix = subscribers.Length - 1; ix >= 0; --ix) { 
       var sub = (EventHandler)subscribers[ix]; 
       sub(this, e); 
      } 
     } 
    } 

請小心這是一個有問題的解決方案,您無法控制其他代碼訂閱事件的順序。

+0

我剛剛看到你編輯過你的帖子。事實上,我更喜歡你之前的帖子,因爲它說明了一步一步的過程。你能否再次發佈舊代碼並顯示事件的添加和刪除方法。 – AllSolutions 2013-03-08 19:05:54

+0

在您當前的代碼中,OnCustom被調用的時間並不清楚。 – AllSolutions 2013-03-08 19:07:38

+0

不,沒必要。請致電OnCustom自己提出事件。這是標準的.NET事件提升模式。 – 2013-03-08 19:11:24

相關問題