2010-01-29 12 views
7

Estoy tratando de aprender algunos principios de WCF siguiendo un ejemplo de una aplicación WCF (de Sacha Barber).GetInvocationList de un evento en VB.NET

Ahora me gustaría convertir la función siguiente en 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); 
     } 
    } 
} 

pero tengo algunos problemas, debido a que el siguiente código no es aceptado por el compilador

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 

Dice

Public Shared Event ChatEvent (remitente As Object, e As ChatEventArgs) 'es un caso, y no puede ser llamado directamente

llegando al punto, es posible entonces en VB.NET obtener los controladores vinculados a un determinado evento de alguna otra manera?

Respuesta

7

uso ChatEventEvent (o eventName Evento)

No se mostrarán en IntelliSense, pero los miembros de que lo hará.

VB.NET crea una variable detrás de las escenas, para ocultar la complejidad del codificador ...

Sólo está disponible en la clase que declara el evento (o tal vez sus descendientes)

+0

Solo tenga en cuenta que está utilizando un miembro no documentado en su clase, y (a menos que esté equivocado) esta política de nombres no se garantiza que permanezca igual en futuras versiones del compilador. –

+0

@Adam - Sí, definitivamente no documentado, por lo que he visto, pero no puedo ver que lo cambien a menos que tengan alguna razón para, o al menos brinden una alternativa. En cualquier caso, es la única forma en que puede hacerlo actualmente, sin manejar todas las cosas del evento por su cuenta, como en su ejemplo. Las suyas seguirán funcionando si lo cambian, pero preferiría guardar ese trabajo dada la probabilidad de que cambie. –

5

Probablemente intente escribir este código en una clase que sea descendiente de la clase que declara el evento ChatEvent. Esto no se puede hacer, ya que los eventos solo se pueden tratar como variables (incluida la invocación) en la clase que los declara. Esto se debe a que la palabra clave event en realidad indica al compilador que necesita realizar algunas transformaciones entre bastidores.

Qué sucede

considerar esta declaración:

Public Event MyEvent as EventHandler 

Bastante simple, ¿verdad? Lo que esto hace realidad, sin embargo, es la siguiente (que simplemente no lo veo)

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 

Y cuando se invoca el evento:

RaiseEvent MyEvent(Me, EventArgs.Emtpy) 

En realidad, llama al código en el bloque RaiseEvent.

Editar

Si los acontecimientos en VB.NET no pueden ser tratados como variables en cualquier lugar (que pueden ser tratados como variables en la clase que se declara en C#, por lo que su ejemplo de C# compila), entonces usted tendrá que implementar explícitamente el evento usted mismo. Consulte MSDN page on the Event statement para obtener más información sobre cómo hacerlo. Para resumir, va a querer guardar los múltiples manejadores de eventos (o usar un único manejador de eventos junto con GetInvocationList, como lo intenta hacer ahora). En sus bloques de códigos AddHandler y RemoveHandler, los agregará y eliminará de la lista de controladores de eventos (respectivamente).

usted podría utilizar algo como esto:

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 

Así que ahora, si se llama a

RaiseEvent MyEvent(Me, EventArgs.Emtpy) 

Se elevará el caso de la manera que usted está esperando.

+0

Gracias por la respuesta, pero no creo que sea mi caso. Mi clase se llama ChatService y declara el Evento Compartido ChatEvent y el Sub BroadcastMessage, donde estoy tratando de obtener la InvocationList de ChatEvent. – Drake

+0

@marco: Vea si mis ediciones son más útiles –

+1

en el primer ejemplo anterior, compilerGeneratedName es * siempre * el nombre del evento seguido de la palabra "Evento", entonces, ChatEventEvent, en este caso. –

Cuestiones relacionadas