2010-07-20 52 views
1

我在.NET 4中有一個基於集合的項目。我的意思是說,我有一個主集合,稱之爲「系統」,它由框架組成,它們是每個由卡組成,這些卡又由通道組成。所以,它看起來像System-> Frame-> Card-> Channel。所有這些都表示爲對象,並且它們之間存在父子關係。本質上,Channel只暴露於Card,Card只暴露給Frame,而Frame只暴露給System。在基於集合的項目中傳播事件

理想情況下,我希望只將方法從System類暴露給外部世界。但是,通道,卡片和框架類中會出現關鍵事件。目前,我處理它們的方式是通過傳播。假設Channel中發生了一個事件。此事件首先在Card中提出,然後在Frame中提出,最後在System中提出。你可以看到這是如何產生大量代碼的。但我主要關心的不是代碼,而是性能。

您是否認爲這種傳播會嚴重影響我的表現?有沒有辦法讓它更有效率?我還有什麼其他選擇?我的收藏相對較小。系統是1,框架< 16,卡片< 256,通道< 8192.大多數數據存儲在Channel類中,其中只有原始對象。

EDITS

這裏是我在錄卡,由通道引發的事件代碼:

protected virtual void OnChannelPropertyChanged(Object sender, PFPropertyChangedEventArgs e) 
    { 
     try 
     { 
      EventHandler<PFPropertyChangedEventArgs> handler = ChannelPropertyChanged; 
      TestEventArgs_ChannelPropertyChanged = e; 
      if (handler != null) 
      { 
       handler(sender, e); 
      } 
     } 
     catch (Exception ex) 
     { 
      Milltown.MTCore.mtException mtEx = new Milltown.MTCore.mtException((int)PFExceptions.Exception_Hidden_FuctionLevel, ex, 
      PFCommonVariables.ApplicationPlatform, PFCommonVariables.ApplicationDataSource, "PFCard:OnChannelPropertyChanged"); 
     } 
    } 

當我一個頻道添加到卡的卡類中,我打電話給:

channel.ChannelPropertyChanged += this.OnChannelPropertyChanged; 

回答

2

回答是否影響您的表現的唯一方法是測試它:嘗試一種方法來傳播ev ents,然後直接附加到另一個地方。看哪個更快。這就是說,我無法想象當你有幾個連續的委託調用而不是一個委託調用時,你會發現很多 - 如果有的話 - 對性能產生可衡量的影響。是的,委託調用比實際方法稍慢,因此,在所有情況相同的情況下,增加更多間接層次比常規方法調用具有更大的影響,但這種過早優化的氣味。

你的方法是我會建議,如果有人問如何做你以後的事情。去除它,除非它是一個問題。

編輯

在回答另一個回答您的意見,我想擴大。 C#事件具有所謂的「屬性語法」。如果在一個類中實現明確的,它看起來是這樣的:

private EventHandler eventDelegate; 

public event EventHandler MyEvent 
{ 
    add { eventDelegate += value; } 
    remove { eventDelegate -= value; } 
} 

(實際上,它使用Delegate.Combine,但是這無關緊要這裏)

當您連接到一個事件,它實際上調用了add代碼,傳遞給代表附加爲value; remove也是如此。

當您使用速記事件語法如下:

public event EventHandler MyEvent; 

它實際上這是非常相似,我上面貼的被子下生成代碼。但是,如果您明確說明,則可以在addremove處理程序中執行任何您喜歡的操作。這意味着您可以將目標委託重定向到其他位置。在其他答案的情況下,它將該委託重定向到一個子對象。

這將工作當且僅當具備以下條件:

  1. 有一個1:父母和子女,以及相關的對象之間的相關性1不會改變
  2. 露出參考到子對象(如object)是可以接受的

如果你有多個孩子,這在技術上是可以做到的(你可以只遍歷並附着於所有的人都在add並刪除它們在remove),但更難以管理。如果事件附加後相關對象或對象集合可能發生變化,則實際上不可能進行協調。另外,如果您的事件遵循事件的推薦做法(您將觸發對象傳遞爲sender),那麼因爲您將目標直接附加到子事件而不是自己提高,那麼您將會通過這個參數暴露對子對象的引用。我不知道這是否與您的相關或可接受,,但它應該被認爲是

+0

+1表示「優化前測量」。 – 2010-07-20 15:40:30

3

您可以在系統類做到這一點:

event EventHandler FrameEvent 
{ 
    add { this.frame.FrameEvent += value; } 
    remove { this.frame.FrameEvent -= value; } 
} 

因此,如果客戶做這個

system.FrameEvent += Handler; 

處理程序是真正附着在框架類的事件。

+0

你是什麼意思'真的'附加? – sbenderli 2010-07-20 15:35:11

+0

Henrik的解決方案很聰明。一方面,該事件暴露在系統級別。另一方面,它在幀級執行,無需重新發信號通知事件。 – 2010-07-20 15:40:04

+1

如果父母和孩子之間存在1:1的相關性,那麼這將起作用。但是,如果您希望在給定子對象觸發事件時觸發單個事件,則必須使用現在的解決方案。請注意,這也會(如果遵循標準事件實踐)通過事件參數的'sender'屬性暴露子類引用,因爲子類將直接向消費​​者發信號。 – 2010-07-20 15:41:00