我们有一个客户呼叫 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
而不是FromEventPattern
?看起来有点反复试验。
“使用 FromEvent 处理事件在结构上看起来不像 .NET 事件模式(即不基于发送者、事件参数),而使用 FromEventPattern 处理基于模式的事件。” - Bart De Smet(Rx 团队)
为了进一步详细说明这一点,您通常可以根据您要观察的类中使用的事件类型来确定何时选择
FromEvent
与 FromEventPattern
之一。当您的事件属于 FromEventPattern
类型或通用
EventHandler
类型时,请使用 EventHandler<T>
。当您使用自定义的非通用事件处理程序类型时,请使用 FromEvent
。
以下示例直接取自 Rx wiki,其中有很多很好的示例 - 准确地说,其中有 101 个。
FromEventPattern(使用通用事件处理程序):
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 );
}
}
来自事件:
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();