如何正确观察非标准事件? [英] How to properly observe non-standard events?

查看:38
本文介绍了如何正确观察非标准事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Reactive Extensions 的新手,正在处理一个具有如下定义事件的 COM 库:

I am new to Reactive Extensions, and dealing with a COM Library that has events defined like this:

public delegate void MyDelegate(int requestId, double price, int amount);
public event MyDelegate MyEvent;

我如何正确观察这一点?我尝试使用 Observable.FromEvent() 但由于事件的参数不是 EventArgs 类型,我看不到 FromEvent()FromEventPattern() 会起作用.

How do I properly observe this? I tried using Observable.FromEvent() but as the event's parameters are not of type EventArgs I don't see how FromEvent() or FromEventPattern() is going to work.

我目前的解决方法是将自定义委托附加到事件,然后调用 Subject.OnNext() 但我猜这不是我应该做的.

My current workaround is to attach a custom delegate to the event then invoke a Subject.OnNext() but I am guessing that's not how I should do it.

以下是我当前解决方法的示例:

Here's an example of my current workaround:

        MyEvent += new MyDelegate((int requestId, double price, int amount) =>
        {
            Task.Run(() =>
            {
                var args = new MyArgs()
                {
                    requestId = requestId,
                    price = price,
                    amount = amount,
                };
                this.mySubject.OnNext(args);
            });
        });

推荐答案

有一个特殊的 FromEvent 重载.让你的头脑有点傻,但函数签名看起来像:

There is a special overload of FromEvent for it. It is a little goofy to get your head around but the function signature looks like:

IObservable<TEventArgs> FromEvent<TDelegate, TEventArgs>(Func<Action<TEventArgs>, TDelegate> conversion, 
                                                         Action<TDelegate> addHandler, 
                                                         Action<TDelegate> removeHandler);

转换函数是这里的重要部分,基本上你是在告诉 Rx 你的委托如何映射到一个具体的类型.

The conversion function is the important part here, basically you are telling Rx how your delegate maps to a concrete type.

在您的场景中,它最终看起来像这样:

In your scenario it ends up looking something like this:

Observable.FromEvent<MyDelegate, MyArgs>(
  converter => new MyDelegate(
                  (id, price, amount) => converter(new MyArgs { 
                                                        RequestId = id, 
                                                        Price = price, 
                                                        Amount = amount
                                                       })
               ),
  handler => MyEvent += handler,
  handler => MyEvent -= handler);

那么这一切是为了什么?在内部,它类似于您正在做的事情(我将从概念上解释它的作用,因为实现稍微复杂一些).进行新订阅时,将使用作为 converter 参数传入的 observer.OnNext 调用转换函数.这个 lambda 将返回一个新的 MyDelegate 实例,它包装了我们提供的转换函数 ((id, price, amount) => ...).这是然后传递给 handler => 的内容.MyEvent += handler 方法.

So what is all this doing? Internally, it is similar to what you are doing (I'll paraphrase what it does conceptually, since the implementation is slightly more complicated). When a new subscription is made, the conversion function will be invoked with observer.OnNext passed in as the converter argument. This lambda will return a new MyDelegate instance that wraps the conversion function that we provided ((id, price, amount) => ...). This is what is then passed to the handler => MyEvent += handler method.

之后,每次触发事件时,它都会调用我们的 lambda 方法并将传递的参数转换为 MyArgs 的实例,然后将其传递给 converter/observer.OnNext.

After that each time the event is fired it will call our lambda method and convert the passed arguments into an instance of MyArgs which is then delivered to converter/observer.OnNext.

此外,除了所有这些魔法之外,它还将在您完成后清理事件处理程序,优雅地将异常传递到下游,并通过在多个观察者之间共享单个事件处理程序来管理内存.

In addition, to all that magic it will also take care of cleaning up the event handlers when you are done with it, gracefully hand exceptions down stream and will manage the memory over head by sharing a single event handler across multiple observers.

源代码

这篇关于如何正确观察非标准事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆