VB.NET中事件的GetInvocationList

时间:2010-01-29 13:49:59

标签: .net vb.net events delegates

我试图通过遵循WCF应用程序(来自Sacha Barber)的示例来学习一些WCF原则。

现在我想将以下函数转换为VB.NET

private void BroadcastMessage(ChatEventArgs e)
{

    ChatEventHandler temp = ChatEvent;

    if (temp != null)
    {
        foreach (ChatEventHandler handler in temp.GetInvocationList())
        {
            handler.BeginInvoke(this, e, new AsyncCallback(EndAsync), null);
        }
    }
}

但是我遇到了一些问题,因为编译器不接受以下代码

Private Sub BroadcastMessage(ByVal e As ChatEventArgs)

    Dim handlers As EventHandler(Of ChatEventArgs) = ChatEvent

    If handlers IsNot Nothing Then

        For Each handler As EventHandler(Of ChatEventArgs) In handlers.GetInvocationList()

            handler.BeginInvoke(Me, e, New AsyncCallback(AddressOf EndAsync), Nothing)

        Next

    End If

End Sub

它说

  

公共共享事件ChatEvent(发件人   As Object,e As ChatEventArgs)'是一个   事件,不能直接调用

说到这一点,是否可以在VB.NET中获取以某种其他方式链接到某个事件的处理程序?

2 个答案:

答案 0 :(得分:8)

使用ChatEventEvent(或 EventName 事件)

它不会出现在intellisense中,但它的成员会出现。

VB.NET在幕后创建一个变量,以隐藏编码器的复杂性......

仅在声明事件的类(或可能是其后代)

中可用

答案 1 :(得分:6)

您可能尝试将此代码编写在类中,该类是声明ChatEvent事件的类的后代。这是不可能的,因为事件只能在声明它们的类中被视为变量(包括调用它们)。这是因为event关键字实际上向编译器指示它需要执行一些幕后转换。

发生了什么

考虑这个声明:

Public Event MyEvent as EventHandler

够简单吧?然而,实际上这是什么(你只是看不到它)

Private compilerGeneratedName as EventHandler

Public Event MyEvent as EventHandler
    AddHandler(ByVal value as EventHandler)
        compilerGeneratedName += value
    End AddHandler
    RemoveHandler(ByVal value as EventHandler)
        compilerGeneratedName -= value
    End RemoveHandler
    RaiseEvent(ByVal sender as Object, ByVal e as EventArgs)
        compilerGeneratedName.Invoke(sender, e)
    End RaiseEvent
End Event

当你调用这个事件时:

RaiseEvent MyEvent(Me, EventArgs.Emtpy)

它实际上调用RaiseEvent块中的代码。

修改

如果VB.NET中的事件不能被视为变量 where (它们可以被视为C#中声明类中的变量,这就是你的C#示例编译的原因),那么你'我必须自己明确地实现这个事件。有关如何执行此操作的详细信息,请参阅MSDN page on the Event statement。总而言之,您需要一些方法来存储多个事件处理程序(或者使用单个事件处理程序以及GetInvocationList,就像您现在尝试的那样)。在AddHandlerRemoveHandler代码块中,您将分别添加和删除事件处理程序列表。

您可以使用以下内容:

Private myEventList as New List(Of EventHandler)

Public Custom Event MyEvent as EventHandler
    AddHandler(ByVal value as EventHandler)
        myEventList.Add(value)
    End AddHandler
    RemoveHandler(ByVal value as EventHandler)
        myEventList.Remove(value)
    End RemoveHandler
    RaiseEvent(ByVal sender as Object, ByVal e as EventArgs)
        For Each evt in myEventList
           evt.BeginInvoke(sender, e, New AsyncCallback(AddressOf EndAsync), Nothing)
        Next
    EndRaiseEvent
End Event

现在,如果你打电话

RaiseEvent MyEvent(Me, EventArgs.Emtpy)

它会以你期待的方式举办活动。