web-dev-qa-db-fra.com

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

Nous avons un client qui appelle vers une file d'attente TIBCO EMS et nous câblons les événements comme ceci:

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

Lorsque j'appelle response.Subscribe(...) j'obtiens System.ArgumentException "Erreur de liaison à la méthode cible".

Je peux le faire fonctionner avec Observable.FromEventPattern<EMSMessageEventArgs>(msgConsumer, "MessageHandler") mais alors il a l'événement en tant que chaîne et tout simplement 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? Cela semble un peu d'essai et d'erreur.

56
baralong

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

63

Pour développer un peu plus loin, vous pouvez généralement déterminer quand choisir l'un des 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 extraits directement du wiki Rx , qui a 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);
    }
}
18
joelmdev

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