53 votes

Quand utiliser Observable.FromEventPattern plutôt que Observable.FromEvent ?

Nous avons un client qui appelle une file d'attente TIBCO EMS et nous câblons les événements de la manière suivante :

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);

Quand j'appelle response.Subscribe(...) J'obtiens System.ArgumentException "Error binding to target method".

Je peux le faire fonctionner avec Observable.FromEventPattern<EMSMessageEventArgs>(msgConsumer, "MessageHandler") mais alors l'événement est une chaîne de caractères et ce n'est pas aussi propre.

J'ai aussi IObservable<EventPattern<EMSMessageEventArgs>> plutôt que IObservable<EMSMessageEventArgs>

Ce que j'aimerais comprendre c'est : quand dois-je utiliser FromEvent sur FromEventPattern ? Il semble qu'il faille procéder par essais et erreurs.

64voto

Richard Hein Points 6697

"Utilisez FromEvent pour les événements qui ne ressemblent pas structurellement à un modèle d'événement .NET (c'est-à-dire qui ne sont pas basés sur l'expéditeur, les arguments de l'événement), et utilisez FromEventPattern pour ceux qui sont basés sur un modèle. " - Bart De Smet (équipe Rx)

19voto

joelmdev Points 2215

Pour aller un peu plus loin, vous pouvez généralement déterminer quand choisir l'une des options suivantes FromEvent vs FromEventPattern par le type d'événement utilisé dans la classe que vous essayez d'observer. Utilisez FromEventPattern lorsque votre événement est de type EventHandler ou le générique EventHandler<T> . Utilisez FromEvent lorsque vous utilisez un type de gestionnaire d'événements personnalisé et non générique. Les exemples suivants sont tirés directement de la page Rx wiki qui contient beaucoup de bons exemples. 101 d'entre eux pour être exact.

FromEventPattern (avec EventHandler générique) :

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);
    }
}

10voto

MovGP0 Points 77

Apparemment, la nouvelle syntaxe a un peu changé. La syntaxe actuelle est la suivante :

// 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();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X