我在找一些指针,在实现自定义中的事件VB.NET (Visual Studio2008.净3.5).

我知道"经常"(非自定义)的事件都是实际上的代表们,所以我想利用与会代表在实现一个自定义事件。另一方面, 安德鲁Troelsen's "亲VB2008年。净3.5平台" 书中使用的收集类型在他的所有定义的事件的实例,以及Microsoft的 样本代码 匹配线的思想。

所以我的问题是:什么样的考虑应当我们当选择一个设计过其他的?有哪些优点和缺点的每个设计?哪些类似于内实施的"正常"的事件?

下面是一样的代码表明了两种设计。

Public Class SomeClass
    Private _SomeEventListeners As EventHandler
    Public Custom Event SomeEvent As EventHandler
        AddHandler(ByVal value As EventHandler)
            _SomeEventListeners = [Delegate].Combine(_SomeEventListeners, value)
        End AddHandler

        RemoveHandler(ByVal value As EventHandler)
            _SomeEventListeners = [Delegate].Remove(_SomeEventListeners, value)
        End RemoveHandler

        RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs)
            _SomeEventListeners.Invoke(sender, e)
        End RaiseEvent
    End Event

    Private _OtherEventListeners As New List(Of EventHandler)
    Public Custom Event OtherEvent As EventHandler
        AddHandler(ByVal value As EventHandler)
            _OtherEventListeners.Add(value)
        End AddHandler

        RemoveHandler(ByVal value As EventHandler)
            _OtherEventListeners.Remove(value)
        End RemoveHandler

        RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs)
            For Each handler In _OtherEventListeners
                handler(sender, e)
            Next
        End RaiseEvent
    End Event
End Class
有帮助吗?

解决方案

我想说的使用简单的代表;只是-它是 已经 (内部)一个列表,所以你是重复努力通过包装它 List<T>.你还有开销的额外清单的目的和阵列,这可能是空的,因此更多的影响垃圾收集等。

此外,如果你正在做的 很多 为此,考虑 EventHandlerList, ,其存在提供有效的访问 稀疏 事件-即你想要获得大量的事件,但是他们中的许多人可以未分配。

第一个例子是远远更接近于"标准"事件(尽管你可能想看,用于未分配/null处理程序打电话时 Invoke, ,因为它可能是null)。此外,请注意,某些语言(老实说,我不知道什么VB在这里所做的)适用同步的事件,但在现实中很少几个事件 真的 需要线安全,以便能够矫枉过正。

编辑 它也会发生这有一个 功能 它们之间的不同:

  • 委托方式对待不同的情况下具有相同目标的方法/实例作为平等(我不认为 List<T> 会)
  • 重复各位代表:委托将删除最后的第一次;列表中删除早先
  • 复合材料:加,添加B,而删除(A+B)-的委托,这应产生空/空,但该名单一方法将保留A和B(与(A+B)消除未能找到任何东西)

其他提示

使用MulticastDelegate举行一个名单的订阅的事件无疑是一个可行的办法,但不是一个我特别希望。添加或删除的事件从一个MulticastDelegate,一个人必须做的两件事之一:

  1. 获得锁,创建一个新的委托从旧的一个,但有一个事件中添加或删除,设置该代表指针指向这一委托,然后释放锁
  2. 复制一个参照旧的委托,创建一个新的委托,但有一个事件增加或删除,使用互锁。CompareExchange储存的参考新的一个,如果旧不变,并开始,所有超过如果CompareExchange失败。

后一种办法可能提供稍好业绩,如果没有争论,但是可以执行严重,如果许多线程的同时试图添加或删除的事件。一个利用后一种做法,虽然是没有危险的螺纹死亡,同时保持锁。

既没有做法似乎尤其是清洁的。如果一个计划在援引的所有事件通过只援引一个委托事件的调用性可以抵消增加/删除的表现。另一方面,如果一个计划使用GetInvocationList以来包裹的事件的呼吁在尝试/抓住街区,一个可能是更好只是一个采用(适当地锁定)列表或其他此类数据的结构。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top