Когда использовать Observable.FromEventPattern, а не Observable.FromEvent? - PullRequest
52 голосов
/ 24 июня 2011

У нас есть клиент, вызывающий очередь TIBCO EMS, и проводим такие события следующим образом:

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

Когда я вызываю response.Subscribe(...), я получаю System.ArgumentException "Ошибка привязки к целиmethod. "

Я могу заставить его работать с Observable.FromEventPattern<EMSMessageEventArgs>(msgConsumer, "MessageHandler"), но тогда оно получает событие в виде строки и просто не так чисто.

Также у меня есть IObservable<EventPattern<EMSMessageEventArgs>>, а не IObservable<EMSMessageEventArgs>

Что я хотел бы понять: когда мне следует использовать FromEvent вместо FromEventPattern?Кажется, немного проб и ошибок.

Ответы [ 3 ]

63 голосов
/ 24 июня 2011

«Используйте FromEvent для событий, которые структурно не похожи на шаблон событий .NET (т.е. не основанный на отправителях, аргументах событий), и используйте FromEventPattern для событий на основе шаблонов». - Барт Де Смет (Rx team)

18 голосов
/ 03 ноября 2014

Чтобы подробнее остановиться на этом, вы обычно можете определить, когда выбрать один из FromEvent против FromEventPattern по типу события, используемого в классе, который вы пытаетесь наблюдать. Используйте FromEventPattern, когда ваше событие имеет тип EventHandler или общий EventHandler<T>. Используйте FromEvent, когда вы используете нестандартный тип обработчика событий. Следующие примеры взяты непосредственно из Rx wiki , в котором есть много хороших примеров - 101 из них , если быть точным.

FromEventPattern (с универсальным EventHandler) :

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);
    }
}
7 голосов
/ 01 мая 2015

Видимо, новый синтаксис немного изменился. Текущий синтаксис следующий:

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