Ответ 1
"Использовать FromEvent для событий структурно не похожи на шаблон события .NET(т.е. не на основе отправителя, события args) и использовать FromEventPattern для шаблонов". - Барт Де Смит (команда Rx)
У нас есть клиент, который звонит в очередь 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 "Ошибка привязки к целевому методу".
Я могу заставить его работать с Observable.FromEventPattern<EMSMessageEventArgs>(msgConsumer, "MessageHandler")
, но потом он получил событие как строку и просто не так чисто.
Также у меня IObservable<EventPattern<EMSMessageEventArgs>>
, а не IObservable<EMSMessageEventArgs>
Что я хотел бы понять: когда следует использовать FromEvent
over FromEventPattern
? Кажется, это немного проб и ошибок.
"Использовать FromEvent для событий структурно не похожи на шаблон события .NET(т.е. не на основе отправителя, события args) и использовать FromEventPattern для шаблонов". - Барт Де Смит (команда Rx)
Чтобы подробнее остановиться на этом, вы можете определить, когда выбрать один из FromEvent
vs 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);
}
}
По-видимому, новый синтаксис немного изменился. Текущий синтаксис следующий:
// 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();