2011-06-24 34 views
47

Tenemos un cliente que llama a una cola de TIBCO EMS y están cableando los eventos como este:Cuándo utilizar Observable.FromEventPattern en lugar de Observable.FromEvent?

var msgConsumer = _session.CreateConsumer(responseQueue); 
var response = Observable.FromEvent<EMSMessageHandler,EMSMessageEventArgs> 
      (h => msgConsumer.MessageHandler += h, h => msgConsumer.MessageHandler -= h) 
      .Where(arg => arg.Message.CorrelationID == message.MessageID); 

Cuando llamo response.Subscribe(...) me sale System.ArgumentException "error de unirse a secuencias diana método."

Puedo hacer que funcione con Observable.FromEventPattern<EMSMessageEventArgs>(msgConsumer, "MessageHandler") pero luego tiene el evento como una cadena y no tan limpio.

También he IObservable<EventPattern<EMSMessageEventArgs>> en lugar de IObservable<EMSMessageEventArgs>

Lo que me gustaría que entender es: ¿cuándo debo usar FromEvent sobre FromEventPattern? Parece un poco de prueba y error.

+1

Existen otras sobrecargas de FromEventPattern que no tienen un parámetro de cadena si a usted le preocupa. –

+0

Gracias, me había perdido esa sobrecarga. Sí, la cadena me molestó, pero era más la diferencia entre mi FromEvent y FromEventPattern (ver comentario en tu respuesta a continuación) – baralong

+0

Ver http://stackoverflow.com/questions/19895373/how-to-use-observable-fromevent- instead-of-fromeventpattern-and-avoid-string-lit para obtener una explicación completa de FromEvent también. –

Respuesta

60

"Usar FromEvent para eventos estructuralmente no se ve como un patrón de evento .NET (es decir, no se basa en remitente, eventos args), y usa FromEventPattern para los basados ​​en patrones." - Bart De Smet (Rx team)

+11

Gracias, encontré ese comentario, pero creo que no entendí lo que significaba. ¿Sería correcto decirlo? El patrón de evento .NET tiene una firma de Delegate void Handler (objeto remitente, EventArgs args) si el evento coincide con el uso de FromEventPattern (más detallado pero, quizás un poco más claro) – baralong

+1

@baralong, eso es correcto. ¡Aclamaciones! –

11

Para más detalles sobre esto un poco más lejos, normalmente se puede determinar cuándo se debe elegir uno de los FromEvent vs FromEventPattern por el tipo de evento se utiliza en la clase que usted está tratando de observar. Use FromEventPattern cuando su evento sea del tipo EventHandler o el genérico EventHandler<T>. Use FromEvent cuando esté usando un tipo de controlador de eventos personalizado y no genérico. Los siguientes ejemplos se han eliminado directamente del Rx wiki, que tiene muchos buenos ejemplos: 101 of them para ser exactos.

FromEventPattern (con manejador de sucesos genérico) :

class ObserveEvent_Generic 
{ 
    public class SomeEventArgs : EventArgs { } 
    public static event EventHandler<SomeEventArgs> GenericEvent; 

    static void Main() 
    { 
     // To consume GenericEvent as an IObservable: 
     IObservable<EventPattern<SomeEventArgs>> eventAsObservable = Observable.FromEventPattern<SomeEventArgs>(
      ev => GenericEvent += ev, 
      ev => GenericEvent -= ev); 
    } 
} 

FromEvent:

class ObserveEvent_NonGeneric 
{ 
    public class SomeEventArgs : EventArgs { } 
    public delegate void SomeNonGenericEventHandler(object sender, SomeEventArgs e); 
    public static event SomeNonGenericEventHandler NonGenericEvent; 

    static void Main() 
    { 
     // To consume NonGenericEvent as an IObservable, first inspect the type of EventArgs used in the second parameter of the delegate. 
     // In this case, it is SomeEventArgs. Then, use as shown below. 
     IObservable<IEvent<SomeEventArgs>> eventAsObservable = Observable.FromEvent(
      (EventHandler<SomeEventArgs> ev) => new SomeNonGenericEventHandler(ev), 
      ev => NonGenericEvent += ev, 
      ev => NonGenericEvent -= ev); 
    } 
} 
+1

Esa es una muy buena explicación. Gracias –

6

Al parecer, la nueva sintaxis ha cambiado un poco. La sintaxis actual es la siguiente:

// get events as observable 
var events = Observable.FromEvent<MouseButtonEventHandler, MouseEventArgs>(
    handler => MouseUp += handler, handler => MouseUp -= handler); 

// subscribe to events 
var subscription = events.Subscribe(args => OnMouseUp())); 

// always dispose subscriptions! 
subscription.Dispose(); 
Cuestiones relacionadas