2011-03-22 44 views
3

如何避免被處理兩次事件(如果是相同的處理?)避免重複的事件處理程序?

Module Module1 
    Sub Main() 
    Dim item As New Item 
    AddHandler item.TitleChanged, AddressOf Item_TitleChanged 
    AddHandler item.TitleChanged, AddressOf Item_TitleChanged 

    item.Title = "asdf" 

    Stop 
    End Sub 
    Private Sub Item_TitleChanged(sender As Object, e As EventArgs) 
    Console.WriteLine("Title changed!") 
    End Sub 
End Module 

Public Class Item 
    Private m_Title As String 
    Public Property Title() As String 
    Get 
     Return m_Title 
    End Get 
    Set(ByVal value As String) 
     m_Title = value 
     RaiseEvent TitleChanged(Me, EventArgs.Empty) 
    End Set 
    End Property 

    Public Event TitleChanged As EventHandler 
End Class 

輸出:

Title changed! 
Title changed! 

所需的輸出:

Title changed! 

我希望事件管理器檢測到這個事件已經被這個處理器處理了,所以它不應該重新處理(或讀取)它。

回答

0

包裝紙的事件處理程序列表中HashSet將確保處理程序不重複引用,下面的片段替換爲問題的Item類將上述樣品下工作(它不會重新添加處理程序,如果它已經在HashSet):

Public Class Item 
    Private m_Title As String 
    Public Property Title() As String 
    Get 
     Return m_Title 
    End Get 
    Set(ByVal value As String) 
     m_Title = value 
     RaiseEvent TitleChanged(Me, EventArgs.Empty) 
    End Set 
    End Property 

    Private handlers As New HashSet(Of EventHandler) 

    Public Custom Event TitleChanged As EventHandler 
    AddHandler(value As EventHandler) 
     handlers.Add(value) 
    End AddHandler 

    RemoveHandler(value As EventHandler) 
     handlers.Remove(value) 
    End RemoveHandler 

    RaiseEvent(sender As Object, e As System.EventArgs) 
     For Each handler In handlers.Where(Function(h) h IsNot Nothing) 
     handler(sender, e) 
     Next 
    End RaiseEvent 
    End Event 
End Class 
+0

這看起來像內存泄漏。 – 2015-06-24 16:53:24

6

你也可以只是一直AddHandler之前調用RemoveHandler。我發現這在特定情況下很實用。

+1

雖然有作品,但我認爲這不是正確的態度。 – Shimmy 2011-03-27 05:31:35

+0

謹慎解釋爲什麼? – tenfour 2011-03-27 10:19:27

+0

因爲在添加它們之前,它總是會刪除事件。它對我來說看起來有些sl sl。 – Shimmy 2011-03-27 11:51:40