簡體   English   中英

如何創建一個弱引用事件處理程序?

[英]How to create a Weak Referenced Event Handler?

我正在研究如何正確創建弱引用事件處理程序。 由於WPF已經有一個避免事件內存泄漏的解決方案,我反編譯了“WeakEventManager”類並花了一些時間來分析它。

正如我所發現的,“WeakEventManager”類依賴於創建和存儲對目標對象以及事件處理程序委托的弱引用。 以下是一些代碼段:

this._list.Add(new WeakEventManager.Listener(target, handler));


  public Listener(object target, Delegate handler)
  {
       this._target = new WeakReference(target);
       this._handler = new WeakReference((object) handler);
  }

我問自己,這個簡單的解決方案是否已經有效,或者我忽略了一個重要方面,因為我在互聯網上找到的大多數其他解決方案都很復雜且難以理解。 到目前為止,我能找到的最佳解決方案是使用未綁定的委托。 這是某種包裝器委托,它將事件處理程序和事件訂閱者實例作為參數(是的,它要求在委托調用期間傳遞事件訂閱者對象)。

你可以在這里找到這篇精彩的文章:

http://diditwith.net/CommentView,guid,aacdb8ae-7baa-4423-a953-c18c1c7940ab.aspx#commentstart

“WeakEventManager”類不依賴於了解訂閱者類或任何其他信息。 除此之外,它還可以與匿名代表合作。 為什么開發人員花了這么多時間編寫一個不僅工作而且使用方便的解決方案,如果解決方案只要求他們存儲對委托的弱引用? 有什么收獲?

更新 :因為有人貶低了這個問題(可能有點不明確),我想提出一個更精確的問題:

這個源代碼首先是創建一個有效的弱事件處理程序嗎? 如果沒有,缺少什么?

我忽略了一個重要方面

是的,一個重要的。 你換了另一個“泄漏”。 您現在可以防止收集WeakReference對象,而不是阻止事件訂閱者對象收集垃圾。 你沒有領先。

需要一種機制來清除那些陳舊的WeakReferences。 當IsAlive屬性返回false時,您不再需要它們,然后將其從_list刪除。 但你必須單獨檢查, 有些代碼需要處理。 一個明顯的選擇是檢查何時添加事件或何時觸發事件。 但這還不夠,因為客戶端代碼只會在初始化時添加,並且無法保證事件始終被觸發。

所以, 某種方案的需要以后做。 任何事都是可能的,沒有什么是非常理想的,因為經常沒有完成任何工作需要很多繁忙的工作。 做出正確的選擇很重要。 而這當然也包括這樣做的話,那往往是一個創可貼在設計問題。

WeakEventManager背后的想法是它保留一個對事件的目標對象的弱引用列表和它必須調用的處理程序列表,但不“將它們綁在一起”(直接訂閱事件通常會這樣做),允許目標是垃圾收集(並定期檢查,以便在源被垃圾收集時相應地清空“訂閱的”委托列表)。

這聽起來很簡單,需要大量的管道代碼,這就是WeakEventManager所做的一切(以易於使用的方式為您做管道工作)。

如果你將WeakEventManager克隆到你自己的實現(或者使用內置的)並且它就是這樣做,那么是的,這就是你需要做的全部。 如果這不是你問的問題,那么這個問題我不清楚。

這個源代碼首先是創建一個有效的弱事件處理程序嗎? 如果沒有,缺少什么?

這是最重要的一點, Listener類的其余部分也很重要,更不用說支持這個非委托事件處理程序所需的手動管道。

例如,檢查一下ListenerList.DeliverEvent ,它比通常的Invoke調用更復雜一些。

基本上,正常事件系統假設強引用,因此為了使用WeakReference您最終必須自己添加大量翻譯邏輯,以及決定如何處理因使用WeakReference而從未觸發的事件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM