GetInvocationList события в VB.NET



Я пытаюсь изучить некоторые принципы WCF, следуя примеру приложения WCF (от Sacha Barber).

Теперь я хотел бы преобразовать следующую функцию в 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 (отправитель Как объект, как ChatEventArgs) - это событие, и не может быть вызвано непосредственно

Переходим к сути, возможно ли тогда в VB.NET связать обработчики с определенным событием каким-то другим способом?

133   2  

2 ответов:

Использовать ChatEventEvent (или Имя_событияСобытие)

Он не будет отображаться в intellisense, но его члены будут.

VB.NET создает переменную за кулисами, чтобы скрыть сложность от верстальщика...

Это доступно только в классе, который объявляет событие (или, возможно, его потомков)

Вероятно, вы пытаетесь написать этот код в классе, который является потомком класса, объявляющего событие 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.

Edit

Если события в VB.NET не могут быть обработаны как переменные в любом месте (они могут быть обработаны как переменные в объявлении класса В C#, поэтому ваш пример C# компилируется), то вам придется явно реализовать событие самостоятельно. Смотрите страницу MSDN на оператор события для получения дополнительной информации о том, как это сделать. Короче говоря, вам понадобится какой-то способ хранения нескольких обработчиков событий (или использовать один обработчик событий вместе с GetInvocationList, как вы пытаетесь сделать сейчас). В ваших блоках кода AddHandler и RemoveHandler вы будете добавлять и удалять из списка обработчиков событий (соответственно).

Вы могли бы использовать что-то вроде этого:

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)

Это поднимет событие в моде, которую вы ожидающий.

    Ничего не найдено.

Добавить ответ:
Отменить.